2012-04-01 2 views
12

Я пытаюсь установить сетку и обновить ее с помощью большего количества записей через JSON. В этом простом примере я могу достичь требуемой функциональности, но я могу только обновить/нажать одну запись JSON. Я хотел бы иметь возможность добавлять несколько записей через JSON? Как я мог это достичь? Я предположил, что мне, возможно, придется создать какой-то цикл for и подтолкнуть каждый результат JSON к наблюдаемому, но я надеялся, что у нокаута может быть лучший способ обновления/синтаксического анализа через JSON?Обновление Knockout.js Наблюдается от JSON

Heres копией того, что я достиг до сих пор: 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> 

Update это, кажется, работает, но мне интересно, если их это более эффективный метод?

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]); 
     }; 

ответ

22

Вот 3 способа вы могли бы сделать это ... нашел в этой скрипкой: http://jsfiddle.net/johnpapa/nfnbD/

1) Используйте К.О. .utils.arrayPushAll function 2) используйте свою собственную логику 3) Напишите свою собственную функцию по наблюдаемому массиву

Подробнее ...

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); 
+0

помните, что вам может понадобиться создать переменную экземпляра вашей модели, если вы хотите обновить свой наблюдаемый массив от где-то на своей странице, вне самой реальной модели, например: 'вар myModelInstance = новый ViewModel();' ' ko.utils.arrayPushAll (myModelInstance.users(), dataFromServer);' ' myModelInstance.users.pushall –

+1

Является ли это по-прежнему путь с версией 3.1? – Homer

+0

Я задаю тот же вопрос, что и Гомер. Является ли «pushAll» уже в ядре KnockoutJs с версии 3.1. – Samuel

3

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

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

+0

как делает отображение плагинов помочь с проблемой? –

+0

См. Раздел «Расширенное использование» (доступно в связанной статье). С плагином вы можете настроить процесс обновления/создания –

1

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

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

Example in JsFiddle

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

Смежные вопросы