javascript - Ember 异步计算属性返回未定义

标签 javascript ember.js ember-data indexeddb

我正在尝试将属性设置为模型的 async、hasMany 关系的值。但我无法在 then 函数中返回任何值。

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}),
});

我的问题在于 Athlete 的 ObjectController,我试图将 Time hasMany 数组设置为属性。在 then 回调函数之外,我可以正常返回值。但是,在 then 回调中,所有值都返回 undefined/根本不返回。此外,使用 console.log 我始终能够看到代码正在执行。

这是该方法:

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('<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4f3b26222a610f2a2e2c27613b26222a" rel="noreferrer noopener nofollow">[email protected]</a>'),

虽然上面的函数总是返回undefined,但下面的函数(同一 Controller 的一部分)始终如一地工作,没有错误。

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('<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="addeddc1c4d9de83edc8cccec583c0" rel="noreferrer noopener nofollow">[email protected]</a>'),

看了6个小时,我已经不知道去哪里找问题了。我不明白这个问题从何而来。其他人会碰巧知道这个问题是从哪里产生的吗?

注意:我的问题与 Computed property in Ember based on async data 类似尽管我对这个解决方案没有任何运气。

最佳答案

您没有向计算属性返回任何内容,而是向回调函数返回一些内容,该回调函数将被传递给任何链式 promise ,但是如果您返回 promise ,这仍然无济于事,因为将 promise 返回到计算属性不会自动解析 promise 并使用计算属性值的结果。

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

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('<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1c68757179325c797d7f743268757179" rel="noreferrer noopener nofollow">[email protected]</a>'),

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

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('<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a8dcc1c5cddb86e8cdc9cbc086dcc1c5cd" rel="noreferrer noopener nofollow">[email protected]</a>'), //times, not time

关于javascript - Ember 异步计算属性返回未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26569986/

相关文章:

ember.js - 如何在应用程序启动时加载Ember Data数据?

javascript - 在 Javascript 变量中转义引号的通用方法

php - 从单个 javascript 函数向两个不同的 PHP 脚本发送两个 Ajax 请求

javascript - Ember.Select 在使用路由器的应用程序中的 contentBinding

ember.js - 从相关的 "belongs to"路由创建一条记录。断言失败: Assertion Failed: You can only add a 'group' record to this relationship

javascript - 如何在元素的动态范围内添加类 - jQuery

javascript - JQuery Animate 的问题

javascript - Ember Data 在提交时不发送数据

javascript - Ember - 子组件通过父组件更新来自查询参数的属性