如何创建依赖于全局类属性的计算属性?

时间:2013-08-15 13:47:26

标签: ember.js

我想创建一个依赖于全局属性的属性:

App.Test= Em.Object.extend();
App.Test.reopenClass({ all: Em.A() });

App.Other = Em.object.extend({
  stuff: function() {
    return "calculated stuff from this.get('foo') and App.Test.all";
  }.property('foo', 'App.Test.all.@each.bar')
});

作为一个workarround,我可以创建一个观察者并始终使用新的随机值设置一个虚拟属性来触发属性更改,但是有更好的方法吗?

我需要这个来进行一些缓存。我有一个非常疯狂的单线程后端。所以我编写了自己的Model类。所以我尝试重新实现客户端中的一些逻辑以获得更好的缓存。

我有一个Item类(App.Item)和另一个类,其中每个实例都有一个计算的减少的项目列表。

App.Model = Em.Object.extend({
});
App.Model.reopenClass({
  all: Em.A(),
  load: function(hash) {
    return this.get('all').pushObject(this.create(hash));
  }
});

App.Item = App.Model.extend({

});

App.List = App.Model.extend({
  loadedInitItems: false,
  items: function() {
    if(!this.get('loadedInitItems')) { this.set('loadedInitItems', true); Backend.call('thelist', function(item) { App.Item.load(this); }); }
    return App.Item.all.filter(function(item) {
      // heavy filter stuff, depends on a lot of propertys on the current list instance
    });
  }.property('someprops', 'App.Item.all.@each.foo')
});

Backend.call表示一些AJAX的东西

关键是,现在任何项目都可以更改,以便过滤器返回不同的内容。此外,应用程序还有其他地方,用户可以在其中添加项目。我不想再打电话给后端,因为它很慢!而且我知道后端不会修改列表!所以我想缓存它。

这只是我用例的一个简化示例,但我认为已经描述了这一点。实际上,我有这样的时间,超过25000个物体。

2 个答案:

答案 0 :(得分:1)

您是否尝试将“绑定”添加到您的属性,然后添加要绑定到的值?,如下所示:

App.PostsController = Em.ArrayController.extend({
  nameOfYourVariableBinding: "App.SomeObject.propertyYouWantToBindTo"
})

答案 1 :(得分:0)

看起来问题是双重大写字母。所以App.test正在运作,但不是App.Foo.test

但是我能够找到一个使用ArrayProxy的解决方案。

关于这个:

App.Model = Em.Object.extend({
});
App.Model.reopenClass({
    all: Em.A(),
    load: function(hash) {
        return this.get('all').pushObject(this.create(hash));
    }
});

App.Item = App.Model.extend({

});

App.List = App.Model.extend({
    loadedInitItems: false,
    items: function() {
        var self = this;
        if(!this.get('loadedInitItems')) { 
            this.set('loadedInitItems', true);
            Backend.call('thelist', function(item) {
                App.Item.load(this);
            }); 
        }

        return Em.ArrayProxy.extend({
            content: App.Item.all,
            arrangedContent: function() {
                return this.get('content').filter(function(item) {
                    // heavy filter stuff, depends on a lot of propertys on the current list instance
                    // use self.get('someprops')
                })
            }.property('content.@each.foo')
        });
    }.property('someprops')

    items: function() {
        if(!this.get('loadedInitItems')) { this.set('loadedInitItems', true); Backend.call('thelist', function(item) { App.Item.load(this); }); }
        return App.Item.all.filter(function(item) {
// heavy filter stuff, depends on a lot of propertys on the current list instance
});
    }.property('someprops', 'App.Item.all.@each.foo')
});