如何在Ember第一次访问相关记录时加载相关记录?

时间:2014-06-27 04:44:25

标签: ember.js

我有一个计算属性,它获取一个关联的记录并尝试打印它。我第一次获取记录时,它是空的。所有后续访问都能正常工作。它被设置为' async:true',但将其设置为false并不会改变此行为。

MyApp.ThingsController = Ember.ArrayController.extend({
    myProperty: function() {

        var content = this.get('content');

        return content.filter(function(thing) {

            console.log(thing.get('title')); // Since this is a direct attribute on the model, it prints fine.
            var associatedThing = thing.get('associatedThing'), otherThings = [];
            console.log(associatedThing.get('content')); // This is a hasMany attribute on the model, and is null the *first* time, but fine on subsequent accesses.

            otherThings = associatedThing.get('content'); // Obviously doesn't work the first time either.
            return thing.get('title') + otherThings[0].get('name'); // Or similar.

        });

    }.property('content.@each') // adding observers for content.associatedThing.@each does not seem to make any difference.
});

模型如:

MyApp.Thing = DS.Model.extend({

    title: DS.attr('string'),
    associatedThings: DS.hasMany('associatedThing', { async: true })

});

MyApp.AssociatedThing = DS.Model.extend({

    name: DS.attr('string')

});

显然,我不能在这里使用promises,因为我需要从函数返回一个值,所以我不能使用回调(因为我们在计算属性中。)如何在第一次这个工作时使用访问相关记录?

编辑: myProperty ArrayController 上的计算属性,用于显示或隐藏内容

2 个答案:

答案 0 :(得分:0)

实际上,你可以使用承诺,而不是你想的方式。对于hasMany关系,Ember-Data返回PromiseArray。这意味着它返回一个将解析为数组的promise。但与此同时,代理实际上会回复您使用get发出的undefined次请求。然后,当诺言结算时,任何观察者都会被解雇。因此,如果您的属性依赖于associatedThings属性,则在promise解析时进行更新。换句话说,这将按预期工作:

MyApp.Thing = DS.Model.extend({
    title: DS.attr('string'),
    associatedThings: DS.hasMany('associatedThing', { async: true }),
    sum: function() {
        var things = this.get('associatedThings');
        return things.filter(function(thing) {
            return shouldFilterThing(thing);
        });
    }.property('associatedThings.@each.size')
});

另外,请不要被同步发生的事实所困扰。尝试将其从异步更改为同步只会使您的代码更加脆弱。让Ember完成它的工作并为你处理所有的属性和绑定。

答案 1 :(得分:0)

我的解决方案只是访问ArrayController的init方法中的相关数据:

init: function() {

    var content = this.get('content');
    content.forEach(thing) {

        // Prime the data.
        var associatedThings = get('associatedThings');

    });

}

这使一切都按预期工作。