Изменить событие при вычислении списка

У меня есть карта вроде так:

var AppState = can.Map.extend({
  sites: null
});
appstate = new AppState();

список заполняется так:

Site.findAll({}, function(sites) {
  appstate.attr('sites', sites);
});

который я передаю в управление, как это:

new SummaryCtrl("#summaryCtrl", {sites:appstate.compute('sites')});

Элемент управления выглядит так:

var SummaryCtrl = can.Control.extend({
  '{sites} change': function(ev, type, sites) { //this doesn't fire
    var recent = sites.slice(0,25);
    var siteCount = sites.length;
    this.element.html(can.view('summaryTpl', {siteCount:siteCount, recent:recent}));
  }
});

Тогда я делаю это:

var newsite = {blah1:'blahblah', blah2:'blahblah'};
appstate.sites.unshift(newsite);

Но функция '{sites} change "не срабатывает. Есть идеи почему? Спасибо!

2 ответа

Выяснил решение - не уверен, что это лучшее решение, но он подходит для моего использования.

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

Если вам нужно использовать карту, это нормально, но, опять же, не передавайте вычисления свойств на карте, просто обратитесь к самому свойству и инициализируйте как пустой список следующим образом:

var State = can.Map.extend({
  sites: new can.List()
});

http://jsfiddle.net/c7tdma5k/25/

Причина, по которой это не работает, состоит в том, что вычисления изменяются только тогда, когда sites изменения свойств, а не отдельных элементов на сайтах.

Если вы создали вычисления как:

var sites = can.compute(function(){ var sites = appState.attr("sites"); sites.attr("length") return new List().replace(sites) })

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

Другие вопросы по тегам