2013-11-14 2 views
2

С knockoutjs У меня есть наблюдаемый массив, и дочерние элементы также наблюдаемы. Наблюдаемый массив связан через foreach. Когда я обновляю элемент массива, представление не обновляется.нокаут наблюдаемые элементы массива не обновляют вид

Почему?

У меня есть jsfiddle здесь ->http://jsfiddle.net/axUm6/7/

<ul data-bind="foreach: someList"> 
    <li> 
     <div style="float: left" data-bind="text: name"></div> 
     <div style="padding-left: 50px;" class="update">update</div> 
    </li> 
</ul> 

vmTemplate = function() { 
    var self = this; 
    self.someList = ko.observableArray(); 

    self.init = function() { 
     self.someList.push(ko.observable({name: 'test 1'})); 
     self.someList.push(ko.observable({name: 'test 2'}));   

     $(document).on('click', '.update', function() { 
      var itemToUpdate = ko.dataFor(this); 
      self.alertTheList(); 
      itemToUpdate.name = 'test 3';    
      self.alertTheList(); 
      self.someList.valueHasMutated(); 
     }); //on click 
    }; //init 

    self.alertTheList=function(){ 
     var message=''; 
     for(var i=0;i<self.someList().length;i++){ 
      message+=self.someList()[i]().name; 
     } 
     alert(message);   
    };//alertTheList 
}; 

var vm = new vmTemplate(); 
vm.init(); 
ko.applyBindings(vm); 
+1

Это не так, как это должно работать. У вас не должно быть зависимости от представления внутри модели представления, поэтому для начинающих нет обработчиков событий jQuery. Используйте привязку 'click'. Сравните: http://jsfiddle.net/nru85/ – Tomalak

+0

Я обновил свой код, чтобы быть похожим на @ Alexander's, который использует правильную привязку события. Что значит «для начинающих», есть ли что-то еще неправильно? Имейте в виду, что это был образец, чтобы показать мою проблему, поэтому, например, предупреждение состояло в том, чтобы помочь с отладкой. –

+0

Ну, я рассматриваю использование 'ko.dataFor()' unclean в моделях просмотра KO, но оно связано с тем, что у вас есть зависимость от представления. Цель должна состоять в том, чтобы иметь модель представления без внешних зависимостей. (Если вам нужно использовать jQuery, сделайте это в пользовательских привязках и только там.) – Tomalak

ответ

2

Вы должны использовать ItemViewModel с наблюдаемыми свойствами вместо self.someList.push (ko.observable (...)). Посмотрите example. Кроме того, я изменил обработчик события jQuery click для привязки нокаута.

Html:

<ul data-bind="foreach: someList"> 
    <li> 
     <div style="float: left" data-bind="text: name"></div> 
     <div style="padding-left: 50px;" class="update" data-bind="click: $parent.updateName">update</div> 
    </li> 
</ul> 

ViewModel:

ItemViewModel = function(val) { 
    var self = this; 
    self.name = ko.observable(val); 
} 

vmTemplate = function() { 
    var self = this; 
    self.someList = ko.observableArray(); 

    self.init = function() { 
     self.someList.push(new ItemViewModel('test 1')); 
     self.someList.push(new ItemViewModel('test 2'));   
    }; //init 

    self.updateName = function(item) { 
     self.alertTheList(); 
     item.name('test 3');    
     self.alertTheList(); 
    }; //on click 

    self.alertTheList=function(){ 
     var message=''; 
     for(var i=0;i<self.someList().length;i++){ 
      message+=self.someList()[i].name(); 
     } 
     alert(message);   
    };//alertTheList 
}; 

var vm = new vmTemplate(); 
vm.init(); 
ko.applyBindings(vm); 
+0

Точно верно. Спасибо. –

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