2016-07-01 14 views
0

У меня проблема с вычисленной переменной в моей сети с нокаутом. Вот мой код:Вычисленный наблюдаемый не обновляемый UI

function ViewModel() { 
    var self = this; 
    self.seatsRaw = ko.observableArray([]); 
    self.selectedSeatId = ko.observable(); 
    self.session = ko.observable(); 
    self.seats = ko.computed(function(){ 
     var seatsComplete= self.seatsRaw().slice(0); 
     for (var i = 0; i < seatsComplete.length; i++) { 
      if (self.selectedSeatId()) { 
       seatsComplete[i].selected = seatsComplete[i].id == self.selectedSeatId(); 
      } else if (self.session() && Number(self.session().seat) > 0) { 
       seatsComplete[i].selected = seatsComplete[i].id == self.sesion().seat; 
      } else { 
       seatsComplete[i].selected = false; 
      } 
     } 
     return seatsComplete; 
    }); 
    self.selectSeat = function(data,event) { 
    self.selectedSeatId($(this).id); 
    }; 
} 

Итак, я просто получить массив с местами, и я хочу, чтобы добавить поле для каждого объекта в массиве, чтобы показать в пользовательском интерфейсе как «выбрано».

Я прочитал от ajax информацию для сеанса и места raw, и когда я их обновляю, я не вижу никаких изменений в своем интерфейсе.

Почему это происходит? И затем, что мне нужно сделать, чтобы обновить свой интерфейс?

Спасибо!

EDIT

<ul class="seats" data-bind="foreach: seats"> 
     <li data-bind="css: {selected: selected, 'non-selected': !selected}, click: $root.selectSeat"> 
     <a href="#" data-bind="attr: {id: id}"> 
      <img data-bind="attr: {src: baseUrl + 'img/seats/' + image}" /> 
      <p data-bind="text: name"></p> 
     </a> 
     </li> 
</ul> 

Сиденье не ViewModel ... она должна быть?

+0

Параметр 'selected' свойство в' seatsComplete' это, вероятно, должны быть наблюдаемыми. Это означает, что вы должны установить его, используя 'seatComplete [i] .selected (seatComplete [i] .id == self.selectedSeatId())' и т. Д. – user3297291

+0

Извините, но это не работает ... –

+0

Можете ли вы показать свое мнение (HTML) и вид модели? – user3297291

ответ

1

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

Seat - это не ViewModel ... не так ли?

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

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

Ознакомьтесь с этим примером. Из журналов вы видите, что все «работает правильно», но нокаут не будет обновляться. После этого примера я покажу, что произойдет, если мы сделаем selected наблюдаемым.

var seats =[ 
 
    { id: 1, selected: false }, 
 
    { id: 2, selected: true }, 
 
    { id: 3, selected: false } 
 
]; 
 

 
var ViewModel = function() { 
 
    var self = this; 
 
    this.rawSeats = ko.observableArray(seats); 
 
    
 
    this.selectedSeatId = ko.observable(2); 
 
    this.selectSeat = function(data, event) { 
 
    self.selectedSeatId(data.id) 
 
    } 
 
    
 
    this.seats = ko.computed(function() { 
 
    var selectedId = self.selectedSeatId(); 
 
    self.rawSeats().forEach(function(seat) { 
 
     seat.selected = seat.id === selectedId; 
 
    }) 
 
    
 
    console.log(self.rawSeats()); 
 
    return self.rawSeats(); 
 
    
 
    }); 
 
    
 
    } 
 

 
ko.applyBindings(new ViewModel());
.selected { background: yellow }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<ul data-bind="foreach: seats"> 
 
    <li data-bind="css: { selected: selected }, 
 
       text: id, 
 
       click: $root.selectSeat"></li> 
 
</ul>

Теперь, с наблюдаемыми свойствами:

var seats =[ 
 
    { id: 1, selected: ko.observable(false) }, 
 
    { id: 2, selected: ko.observable(true) }, 
 
    { id: 3, selected: ko.observable(false) } 
 
]; 
 

 
var ViewModel = function() { 
 
    var self = this; 
 
    this.rawSeats = ko.observableArray(seats); 
 
    
 
    this.selectedSeatId = ko.observable(2); 
 
    this.selectSeat = function(data, event) { 
 
    self.selectedSeatId(data.id) 
 
    } 
 
    
 
    this.seats = ko.computed(function() { 
 
    var selectedId = self.selectedSeatId(); 
 
    self.rawSeats().forEach(function(seat) { 
 
     seat.selected(seat.id === selectedId); 
 
    }) 
 
    
 
    return self.rawSeats(); 
 
    
 
    }); 
 
    
 
    } 
 

 
ko.applyBindings(new ViewModel());
.selected { background: yellow }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<ul data-bind="foreach: seats"> 
 
    <li data-bind="css: { selected: selected }, 
 
       text: id, 
 
       click: $root.selectSeat"></li> 
 
</ul>

+0

Если вы запустите свой код, вы увидите, что даже если вы измените свой режим просмотра, нажав на li, желтый фон всегда находится во втором ли. –

+0

Вы прочитали весь путь к второму примеру ...? Первый должен был быть сломан, чтобы показать ошибку, я считаю, что вы сделали ... – user3297291

+0

Извините, пользователь ... Он работает! –

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

  • Нет связанных вопросов^_^