knockout: why does my computed function push items

2019-07-19 19:15发布

问题:

I have a computed function, that gets data from a websocket call and pushes it into my observable array

onlineFriends.friendIsOnline = ko.computed(function () {

    socket.on('friend joined', function(data) {

        console.log(data);

        var newObservableItem = onlineFriends.friend(data);

        console.log(newObservableItem);

        onlineFriends.friendsOnline.push(newObservableItem);

        console.log(onlineFriends.friendsOnline())


    });

});

this is the function that converts it into an observable :

onlineFriends.friend = function(data) {

    var self = this;

    self.country = ko.observable(data.country);

    self.firstName = ko.observable("oto");

    self.userName = ko.observable(data.username);

    self.id = ko.observable(data.id);

    self.picture = ko.observable(data.picture);

    self.hasInitMessage = ko.observable(false);

    self.messages =  ko.observableArray([]);

    return self;


};

this is the data i receive from socket listener:

{"firstName":"Mfon","id":"2","address":"vgc","bio":"A man’s gotta make at least one bet a day, else he could be walking around lucky and never know it.","country":"Macau S.A.R.","email":"mfon@gmail.com","firstname":"Mfon","gender":"FEMALE","lastname":"Ukim","locked":false,"money":0,"onlinestatus":"ONLINE","password":"mfon","phonenumber":"08023182388","picture":"generic-avatar.jpg","username":"mfon","usertype":"PLAYER"}

the data from the socket is supposed to be converted into an observable and pushed inside the Observable array, but instead the data itself is pushed into the observable array along with the new observable data, making to items present in my observable array, why is this ?

回答1:

That's because your friend() method isn't returning what you think it does. You intended it to be a "friendFactory" but instead it's returning the entire onlineFriends array and that's because your this refers to the onlineFriends array.

Try to change your method to behave more like a factory/mapping-to-observable instead:

onlineFriends.makeFriend = function(data) {
    return {
        country: ko.observable(data.country),
        firstName: ko.observable("oto"),
        userName: ko.observable(data.username),
        id: ko.observable(data.id),
        picture: ko.observable(data.picture),
        hasInitMessage: ko.observable(false),
        messages: ko.observableArray([])
    };
};

Then in your socket listener:

var newObservableItem = onlineFriends.makeFriend(data);
onlineFriends.friendsOnline.push(newObservableItem);


标签: knockout.js