Обновите Knockout.js, наблюдаемый из JSON

Я пытаюсь создать сетку и обновить ее дополнительными записями через JSON. В этом простом примере я могу достичь требуемой функциональности, но я могу обновить/подтолкнуть только одну запись JSON. Я хотел бы иметь возможность добавлять несколько записей через JSON? Как я мог этого добиться? Я предположил, что мне, возможно, придется создать какой-то цикл for и отправить каждый результат JSON в наблюдаемый, но я надеялся, что у нокаута может быть лучший способ обновления/анализа через 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]);
      };   

person Sparkle    schedule 01.04.2012    source источник


Ответы (3)


Вот 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);
person John Papa    schedule 01.04.2012
comment
имейте в виду, что вам может понадобиться создать переменную экземпляра вашей модели, если вы хотите обновить свой observableArray где-то на своей странице, за пределами самой модели, например: var myModelInstance = new viewModel(); ko.utils.arrayPushAll(myModelInstance.users(), dataFromServer); `myModelInstance.users.pushall - person Flak DiNenno; 05.02.2013
comment
Это все еще способ пойти с версией 3.1? - person Homer; 10.04.2014
comment
Я задаю тот же вопрос, что и Гомер. Является ли pushAll ядром KnockoutJs, начиная с версии 3.1. - person Samuel; 25.04.2014
comment
@ Гомер, к сожалению, это все еще так с 3.1. - person Karlo Medallo; 09.06.2014

Вы можете использовать плагин mapping

См. http://knockoutjs.com/documentation/plugins-mapping.html.

person Vladimir Posvistelik    schedule 01.04.2012
comment
как плагин сопоставления помогает решить проблему? - person dan_l; 27.07.2012
comment
См. раздел Расширенное использование (доступный в связанной статье). С помощью плагина вы можете настроить процесс обновления/создания - person Vladimir Posvistelik; 27.07.2012

Я знаю, что это довольно старый пост, но я наткнулся на него и просто решил показать другой способ сделать это в нокауте, не создавая свой собственный pushAll для будущих посетителей.

Вы можете использовать push.apply в нокауте для наблюдаемого массива. Это позволит вам отправлять несколько элементов с сервера и запускать только одно уведомление.

Пример в JsFiddle

Изменить: дополнительная литература для тех, кто читает это, кто хочет знать, почему использовать push.apply вместо использования push в цикле

person Manatherin    schedule 31.01.2017