12

我正在尝试建立一个网格并通过 JSON 使用更多记录对其进行更新。在这个简单的示例中,我能够实现所需的功能,但我只能更新/推送一条 JSON 记录。我希望能够通过 JSON 添加多条记录?我怎么能做到这一点?我以为我可能必须创建某种 for 循环并将每个 JSON 结果推送到 observable 但我希望淘汰赛可能有更好的方法来通过 JSON 更新/解析?

这是我迄今为止所取得的成就的副本:http: //jsfiddle.net/sparkhill/crSbt/

     function Users(user_id, password) {
    this.user_id = ko.observable();
    this.password = ko.observable();
}

var viewModel = {

    users: ko.observableArray([]),


    addUser: function () {
        this.users.push({

            user_id: "",
            password: ""
        });
    },

    addJSON: function () {


        //Works Fine
        var JSONdataFromServer
        ='{"user_id":"frances","password":"password"}';

        //More than one result - wont map - Would Ideally like to map lots of records at one time
//var JSONdataFromServer ='{"user_id":"frances","password":"password"}, {"user_id":"frances","password":"password"}';

        var dataFromServer = ko.utils.parseJson(JSONdataFromServer);


        this.users.push(dataFromServer);

         //Tried
        //this.users.push(JSON.parse(JSONdataFromServer));


    }

};

viewModel.users();
ko.applyBindings(viewModel);

    </script> 

更新这似乎有效,但我想知道他们是否是一种更有效的方法?

addJSON: function () {

        //Works Fine
        var JSONdataFromServer
        ='[{"user_id":"frances","password":"password"},{"user_id":"timmy","password":"password"}]';

        var results = JSON.parse(JSONdataFromServer);

        var i = results.length;

        for(var i = 0; i < results.length; i++){

            this.users.push(results[i]);
      };   
4

3 回答 3

22

这里有 3 种方法可以做到这一点......在这个小提琴中找到:http: //jsfiddle.net/johnpapa/nfnbD/

1) 使用 ko.utils.arrayPushAll 函数 2) 使用你自己的逻辑 3) 在 observableArray 上编写你自己的函数

细节 ...

1) 如果您使用 ko.utils.arrayPushAll 函数,您也需要调用 valueHasMutated,因为数组实际上会被自身覆盖。除非您告诉它发生了变化,否则可观察性不会触发。您可以这样做:

ko.utils.arrayPushAll(this.users(), dataFromServer);
this.users.valueHasMutated();

2)第二种选择是编写自己的循环逻辑,基本上使用与这样的arrayPushAll函数相同的代码。

for (var i = 0, j = dataFromServer.length; i < j; i++)
this.users.push(dataFromServer[i]);

3) 在 observableArray 上创建自己的函数,如下所示:

ko.observableArray.fn.pushAll = function(valuesToPush) {
        var items = this;
        for (var i = 0, j = valuesToPush.length; i < j; i++){
            items.push(valuesToPush[i]);
        }
        return items;
};

虽然上面的代码会在每次添加项目时通知。因此,最好将它们全部添加,然后通知。这样会更有效率。像这样:

ko.observableArray.fn.pushAll = function(valuesToPush) {
    var underlyingArray = this();
    this.valueWillMutate();
    ko.utils.arrayPushAll(underlyingArray, valuesToPush);
    this.valueHasMutated();
    return this;
};

然后像这样调用它:

this.users.pushAll(dataFromServer);
于 2012-04-01T21:18:13.770 回答
3

你可以使用mapping插件

请参阅http://knockoutjs.com/documentation/plugins-mapping.html

于 2012-04-01T21:04:17.323 回答
1

pushAll我知道这是一篇相当老的帖子,但我偶然发现了它,只是想我会在淘汰赛中展示另一种方法来做到这一点,而无需为任何未来的访问者创建自己的方法。

push.apply您可以在可观察数组上使用in 淘汰赛。这将允许您从服务器推送多个元素并且只触发一个通知。

JsFiddle 中的示例

编辑:对于任何想知道为什么要使用而不是在循环中使用的人的进一步阅读push.applypush

于 2017-01-31T10:23:33.540 回答