Ember异步计算属性返回未定义 [英] Ember async computed property returns undefined

查看:91
本文介绍了Ember异步计算属性返回未定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将一个属性设置为模型的异步值,hasMany关系的值。但是我不能在然后函数中返回任何值。

I am attempting to set a property to the value of a model's async, hasMany relationship. But I'm not able to return any value within the then function.

App.Athlete = DS.Model.extend({
    name: DS.attr('string'),
    age: DS.attr('number'),
    splits: DS.hasMany('split', {async: true}),
    times: DS.hasMany('time', {async: true}),
});

App.Time = DS.Model.extend({
    athlete: DS.belongsTo('athlete', {async:true}),
    race: DS.belongsTo('race', {async: true}),
    time: DS.attr('string'),
});

App.Split = DS.Model.extend({
    distance: DS.attr('string'),
    time: DS.attr('string'),
    athlete: DS.belongsTo('athlete', {async:true}),
    race: DS.belongsTo('race', {async: true}),
});

我的问题在于一个运动员的ObjectController 我试图将 Time hasMany数组设置为属性。在然后回调函数之外,我可以正常返回值。但是,在然后回调之前,所有值都返回 undefined /根本没有。另外,使用 console.log 我一直能看到代码正在执行。

My issue lies in an ObjectController for an Athlete where I am attempting to set the Time hasMany array as a property. Outside of the then callback function I am able to return values normally. However, within the then callback, all values return undefined/not at all. In addition, using console.log I am consistently able to see that the code is being executed.

这里是该方法:

time: function() {
    var raceid= '1';
    this.get('times').then(function(times) {  // returns undefined in this scope
        console.log(times.get('length'));     // consistently displays
        times.forEach(function(time) {
            time.get('race').then(function(timerace) {
                if(timerace.get('id')===raceid) {
                    console.log('match');     // consistently diplays
                    console.log(time.get('time')); // consistently displays
                    return time.get('time'); // returns undefined/not at all
                }
            });
        });
    });
}.property('time.@each.time'),

函数总是返回 undefined ,下面的函数(同一个控制器的一部分)始终没有错误地工作。

While the above function always returns undefined, the function below (a part of the same controller) works consistently without error.

sortedSplits: function(){
    var self = this,
    raceid = '1',
    splits = this.get('splits');
    // filter each split by race
    this.get('splits').filter(function(split) {
        // retrieve race split belongsTo
        split.get('race').then(function(race) {
            // compare race
            return race.get('id') === thisrace; 
        });
    });
    splits = splits.sortBy('m');
    return splits;                // returns correctly
}.property('splits.@each.m'),

看了6个小时后,我再也不知道在哪里寻找问题。我不明白这个问题是从哪里来的。有人会碰巧知道这个问题可以从哪里发生吗?

After looking at it for 6 hours, I no longer know where to look for the issue. I do not understand where this issue is coming from. Would someone else happen to know where that issue can arise from?

注意:我的问题类似于基于异步数据的Ember中的计算属性,尽管我没有任何运气。

Note: My issue is similar to that of Computed property in Ember based on async data although I have not had any luck with that solution.

推荐答案

你没有向计算的属性返回任何东西,你返回的东西回传到任何链接的承诺的回调函数,但仍然如果您退回了承诺,则不会有任何帮助,因为向计算的财产退回承诺不会自动解决承诺,并将结果用于计算的财产的价值。

You aren't returning anything to the computed property, you are returning something to the callback function which is handed off to any chained promises, but that still wouldn't help had you returned the promise, since returning a promise to a computed property doesn't automatically resolve the promise and use the result at the value of the computed property.

您当前的计算属性基本上是这样做的:

Your current computed property is essentially doing this:

time: function() {
    var raceid= '1';
    this.get('times').then(function(times) {  // returns undefined in this scope
        console.log(times.get('length'));     // consistently displays
        times.forEach(function(time) {
            time.get('race').then(function(timerace) {
                if(timerace.get('id')===raceid) {
                    console.log('match');     // consistently diplays
                    console.log(time.get('time')); // consistently displays
                    return time.get('time'); // returns undefined/not at all
                }
            });
        });
    });
  // I'm not returning anything so
  return undefined;
}.property('time.@each.time'),

在这种情况下最简单的方法是使用观察者并设置属性(虽然看起来你不小心观看时间,而不是时间)

In this situation it's easiest to use an observer and set the property (although it looks like you were accidentally watching time, instead of times)

time: null,
timWatcher: function() {
    var raceid= '1',
        self = this;
    this.get('times').then(function(times) {  // returns undefined in this scope
        console.log(times.get('length'));     // consistently displays
        times.forEach(function(time) {
            time.get('race').then(function(timerace) {
                if(timerace.get('id')===raceid) {
                    console.log('match');     // consistently diplays
                    console.log(time.get('time')); // consistently displays
                    self.set('time', time.get('time')); // set property to time value
                }
            });
        });
    });
}.observes('times.@each.time'), //times, not time

这篇关于Ember异步计算属性返回未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆