knockoutjs выбирает объект по щелчку внутри foreach

#button #knockout.js #foreach #click

#кнопка #knockout.js #foreach #нажмите

Вопрос:

Я использую функцию foreach для перечисления данных. И каждая строка содержит кнопку редактирования, которая реагирует на событие щелчка. Но когда вы нажимаете на нее, каждая кнопка внутри списка меняется. Я хочу, чтобы каждая кнопка выбирала каждый элемент, чтобы работать независимо. Пожалуйста, проверьте эту скрипку fiddleDEMO

 var ViewModel = function() {
    var self = this;
this.selectedIndex = ko.observable(0);
this.onIndexSelected = function (index) {
    this.selectedIndex(index);
};
self.buttonState = ko.observable();
self.editar = ko.observable('Edit');   
self.changeState = function(state){
    console.log('changed value');
  console.log(state)
    self.buttonState(state);
}

self.changeButtonValue = function(){
        if (self.buttonState() == false) {
        console.log('entro al if');
        self.changeState(true);
      self.editar('Edit');
  } else {
        console.log('else');
        self.changeState(false);
      self.editar('Save');
  }
}

this.items = [
    {id:1, name: 'Northwoods Prestige'},
    {id:2, name: 'Forest Bay'},
    {id:3, name: 'Timberland'}
];
};
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
  

Спасибо!

Комментарии:

1. Я не вижу, где вы используете ko.observablearray в этом коде. Я почти уверен, что вы не получите желаемого поведения без этого. Кроме того, можете ли вы также поделиться своим view ? Нам нужно посмотреть, как вы обрабатываете каждый элемент внутри foreach цикла в HTML.

Ответ №1:

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

Пример: https://jsfiddle.net/g6t79e4k/11 /

HTML :

 <div>Places</div>
<br>
<div class="row">
  <div data-bind="foreach: items">
    <div class="col-xs-2" data-bind="css: { selected: selectedIndex}, text: name, click: $root.onIndexSelected">
    </div>
    <button data-bind="text: btnText, click: $root.changeButtonValue"></button>   
    <button data-bind="visible:btnState, click: $root.cancelBtn" >Cancel</button>    

  </div>
</div>
  

JS :

 data = [
        {id:1, name: 'Northwoods Prestige'},
        {id:2, name: 'Forest Bay'},
        {id:3, name: 'Timberland'}
    ];

var ViewModel = function() {
    var self = this;
    // map your data and create a new instance of itemViewModel
    self.items = ko.observableArray($.map(data, function (item) {
        return new itemViewModel(item);
    }));

    self.onIndexSelected = function (item) {
         ko.utils.arrayForEach(self.items(), function (item) {
           item.selectedIndex(false);
         });
        item.selectedIndex(true);
    };
    self.changeButtonValue = function(item){
        if (item.btnState()) {
          item.btnText('Edit');
          item.btnState(false);
      } else {
          item.btnText('Save');
          item.btnState(true);
      }
    }  
    self.cancelBtn = function(item){
         item.btnText('Edit');
         item.btnState(false);
    }
};
// sub Model for each item
var itemViewModel = function (data){
  var self = this;
  self.id = ko.observable(data.id);
  self.name = ko.observable(data.name);
  self.selectedIndex = ko.observable(data.id == 1);
  self.btnText = ko.observable("Edit");
  self.btnState = ko.observable(false);
}
var viewModel = new ViewModel();
ko.applyBindings(viewModel);