2014-10-30 65 views
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); 

但 '{}网站变' 功能不火。任何想法为什么?谢谢!

+0

这是一个jsfiddle,sitecount应该是2,而不是1:http://jsfiddle.net/c7tdma5k/6/ – 2014-10-30 12:44:28

回答

1

找出了一个解决方案 - 不知道它是否是最好的解决方案,但它适用于我的使用。

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

如果需要使用地图,这很好,但同样,在地图上的属性单位计算不及格,只是参考属性本身并初始化为空列表,像这样:

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

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

0

这不工作的原因是因为计算只有变化的时候,sites性质的变化,而不是在网站上的个别项目。

如果创建像计算:

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

这会工作。只要在列表中插入或移除项目,计算就会随时更改。但是,您的答案是这样做的更好方法。