【问题标题】:Resolving promise doesn't show data in template解决承诺不显示模板中的数据
【发布时间】:2018-02-24 21:48:04
【问题描述】:

我已经尝试了几个版本/尝试来创建 RSVP.Promise 并将其作为参数返回到我的模板。

所有的 console.log 都给出了合理的值,所以承诺 正在解决。 我遇到的问题(这也是问题)是如何将解析值返回到我的模板。

这是我尝试过的版本:

// in controller.js
testA: Ember.computed('sessionAccount.account.id', function() {
    let _this = this;
    let promise = new Ember.RSVP.Promise(function(resolve, reject) {
        _this.get('store').findAll('accounts2workgroup').then(function(a2ws) {
            let workgroups = [];
            a2ws.forEach(function(a2w){
                if(a2w.get('rights')>1) {
                    workgroups.push(a2w.get('workgroup'));
                }
            });
            console.log(workgroups);
            _this.set('wgAsAdmin', workgroups); // this works
            resolve(Ember.A(workgroups));  //=> [Object] in rendered template
            // return workgroups; // no, not that way
        });
    });

    promise.then(function(data) {
        console.log('did resolve');
        console.log(data);
    })

    return promise; 
}).property('sessionAccount.account.id'),

testB: Ember.computed('sessionAccount.account.id', function() {
    return new Ember.RSVP.Promise(function(resolve, reject) {
    let workgroups = Ember.ArrayProxy.create([{'label': 'TestB Label'}]);
        resolve(workgroups);

    });
}),

testC: Ember.computed(function() {
    return this.store.findAll('artists2workgroup').then(function(a2ws) {
            let workgroups = [];
            a2ws.forEach(function(a2w){
                if(a2w.get('rights')>1) {
                    workgroups.push(a2w.get('workgroup'));
                }
            });
            console.log(workgroups);
            return workgroups; //=> [Object] in rendered
    });
}),

testD: Ember.computed(function() {
    return this.store.findAll('workgroup'); // this of course works, but that's not what I want...
}),

在我的模板中,我像这样测试我的所有测试:

<h4>TestB</h4>
{{#each testB as |wg|}}
        {{wg}}<br>
        {{wg.label}}<br>
{{/each}}
testB: {{testB}}<br>
testB.length: {{testB.length}}<br>

所有(显然是最后一个 testD 除外)都渲染到

测试B
testB: [对象对象]
测试B.长度:

虽然我希望/希望他们展示

测试B

BB-促销
testB:
testB.length: 1

我知道有一些方法可以解决这个问题(我可以在解析 f.e. 时设置另一个属性),但希望以正确的方式进行操作并学习如何执行此操作。 我知道,这些例子没有太大意义。这只是基本功能,一旦我开始运行它就会得到增强。

【问题讨论】:

    标签: javascript ember.js htmlbars


    【解决方案1】:

    首先请避免explicit promise construction antipattern!你也不必保存this,因为ember-cli 中有箭头函数。所以让我们重写你的testA

    testA: Ember.computed('sessionAccount.account.id', function() {
        return this.get('store').findAll('accounts2workgroup').then(a2ws => {
            return workgroups
                .filter(a2w => a2w.get('rights') > 1)
                .map(a2w => a2w.get('workgroup'))
        });
    }).property('sessionAccount.account.id'),
    

    现在这将无法正常工作。这里的问题是 ember 模板不能感知承诺。所以你有三个选择:

    1. 只是不要这样做。通常你可以使用路由 model 钩子来做异步工作。
    2. 使用模板中的 ember-promise-helpers 之类的内容。
    3. 不要只返回一个 Promise。

    如果你不能做到1,我建议你选择3。为此你需要了解PromiseProxyMixin。在 ember-data 中,你有两个 Mixin 的实现,PromiseArrayPromiseObject

    所有ember-data 方法,如findAllfindRecordquery 或异步关系都返回PromiseObject/PromiseArray。所以它们都是promise 常规对象。 promise 部分在路由 model 钩子中很有用,Object/Array 部分对计算属性很有用。所以最简单的方法就是将你的 CP 分成两部分:

    allWorkgroups: Ember.computed(function() {
        return this.get('store').findAll('accounts2workgroup');
    }),
    testA: Ember.computed('sessionAccount.account.id', 'allWorkgroups.@each.rights', 'allWorkgroups.@each.workgroup', function() {
        return this.get('allWorkgroups')
            .filter(a2w => a2w.get('rights') > 1)
            .map(a2w => a2w.get('workgroup'))
    }).property('sessionAccount.account.id'),
    

    这会起作用,因为首先allWorkgroups 将是一个空数组/未解析的promise,但是当promise 解析后,数组会更新,testA CP 将重新计算。

    不过你也可以手动创建一个新的PromiseArray

    testA: Ember.computed('sessionAccount.account.id', 'allWorkgroups.@each.rights', 'allWorkgroups.@each.workgroup', function() {
        const promise = this.get('store').findAll('accounts2workgroup').then(a2ws => {
            return workgroups
                .filter(a2w => a2w.get('rights') > 1)
                .map(a2w => a2w.get('workgroup'))
        });
    
        return DS.PromiseArray.create({promise});
    }).property('sessionAccount.account.id'),
    

    但是你应该知道,如果 Promise 失败,在这两种情况下你都不会得到任何信息!

    【讨论】:

    • 非常感谢您的全面回答!我学到了很多东西! (最引人注目的事实是,模板不知道承诺)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-22
    • 2018-03-19
    • 2016-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多