2

我有一个这样的地图:

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”功能不会触发。知道为什么吗?谢谢!

4

2 回答 2

1

想出了一个解决方案 - 不确定它是否是最好的解决方案,但它可以供我使用。

我意识到列表的计算与列表的接口不同。直觉上,我认为它会。因此,不要将列表的计算传递给控件,​​只需传递列表本身并根据需要在列表上使用 .replace 和 .unshift 。

如果您需要使用地图,那很好,但同样,不要传入地图上属性的计算,只需引用属性本身并将其初始化为空列表,如下所示:

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

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

于 2014-10-30T16:04:51.327 回答
0

这不起作用的原因是计算仅在sites属性更改时更改,而不是站点中的单个项目。

如果您创建了如下计算:

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

这会奏效。每当在列表中插入或删除项目时,计算都会发生变化。但是,您的答案是这样做的更好方法。

于 2014-10-30T19:58:20.190 回答