2013-03-20 4 views
3

HTMLKnockout.js applyBindings дважды продублировать результата

<table cellpadding="0" cellspacing="0" border="0"> 
<thead> 
    <tr><th width="483"><span>Product Name</span></th></tr> 
</thead> 
<tbody data-bind='foreach: basket.model.products()'> 
    <tr><td><div class="ml10 productDetails" data-bind="text: name"></div></td></tr>    
</tbody> 
</table>  

JAVASCRIPT КОД

var ProductLine = function(data) { 
    var self = this; 
    self.name   = ko.observable(data.name); 

}; 

function BasketModel(data) { 
    var self    = this;      
    self.initialData  = ko.observable(data);  
    self.products   = ko.observableArray(); 

    $.each(self.initialData().products,function(i,val){ 
     self.products.push(new ProductLine(this)); 
    }); 
} 
function renderBasket(data){   

    basket = { model: new BasketModel(data)}; 
    ko.applyBindings(basket.model); 
} 
$(document).ready(function(){ 
    var sampleData = [{"name":"product 1"},{"name":"product 2"}]; 
    renderBasket(sampleData); 
}); 

Когда я добавить новый продукт в корзину в пределах АЯКС пост, я вызвать функцию ниже с данными ответа

renderBasket(response.data); 

Пример response.data как [{"name": "product 1"}, {"name": "product 2"}, { «name»: «product 3»}];

В первый: строки таблицы, как:

product 1 
product 2 
product 3 

ПОСЛЕ я добавить новый результат продукт является:

product 1 
product 1 
product 1 
product 2 
product 2 
product 2 
product 3 
product 3 
product 3 

Я попытался ko.cleanNode и basket.model.products .removeAll() перед ko.applyBindings (basket.model); Но я не мог решить проблему.

спасибо.

+0

Когда я сделал это на «успешном успехе ajax», и он сработал. Но я думаю, что это не должно быть реальным решением. basket.model.products.removeAll(); \t \t \t \t \t \t \t \t \t \t \t \t $ .each (ajaxCevap.data.products, функция (я, Валя) { \t \t \t \t \t \t \t basket.model.products.push (новый ProductLine (это)); \t \t \t \t \t \t}); –

+1

Вы никогда не должны вызывать 'applyBindings' дважды, и вы никогда не должны называть' cleanNode', если вы не знаете, что делаете (это не обязательно для почти всех стандартных случаев использования). Этот вопрос задают не реже одного раза в месяц. Пройдите через [Учебники для нокаутов] (http://learn.knockoutjs.com/) – Tyrsius

ответ

5

Вы должны позвонить только ko.applyBindings (из функции $(document).ready). Просто нажмите продукты на наблюдаемом массиве, и вам хорошо идти.

Полный текст приведен на странице http://jsfiddle.net/yCBJ8/5/.

var ProductLine = function (data) { 
     var self = this; 
     self.name = ko.observable(data.name); 
    }, 
    BasketModel = function (data) { 
     var self = this; 

     self.products = ko.observableArray(); 

     self.addToBasket = function (d) { 
      $.each(d, function (i, v) { 
       self.products.push(new ProductLine(this)); 
      }); 
     }; 

     self.replaceBasket = function (d) { 
      self.products.removeAll(); 
      self.addToBasket(d); 
     }; 

     self.addToBasket(data); 
    }; 

$(document).ready(function() { 
    var initialData = [{"name": "product 1"}, {"name": "product 2"}], 
     basket = { 
      model: new BasketModel(initialData) 
     }; 

    ko.applyBindings(basket.model); 
}); 
+0

Существует ошибка, добавленная в addToBasket 'объекта [object Object] не является функцией. Но я получил эту идею. Спасибо. –

+0

Я не вижу ошибки при запуске скрипки? – mhu

+0

Да, это работает. Нет проблем. Извините :) THunk вас так много. –

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