解决承诺不显示模板中的数据
Posted
技术标签:
【中文标题】解决承诺不显示模板中的数据【英文标题】: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. 时设置另一个属性),但希望以正确的方式进行操作并学习如何执行此操作。 我知道,这些例子没有太大意义。这只是基本功能,一旦我开始运行它就会得到增强。
【问题讨论】:
【参考方案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 模板不能感知承诺。所以你有三个选择:
-
只是不要这样做。通常你可以使用路由
model
钩子来做异步工作。
使用模板中的 ember-promise-helpers
之类的内容。
不要只返回一个 Promise。
如果你不能做到1,我建议你选择3。为此你需要了解PromiseProxyMixin
。在 ember-data
中,你有两个 Mixin 的实现,PromiseArray
和 PromiseObject
所有ember-data
方法,如findAll
、findRecord
、query
或异步关系都返回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 失败,在这两种情况下你都不会得到任何信息!
【讨论】:
非常感谢您的全面回答!我学到了很多东西! (最引人注目的事实是,模板不知道承诺)以上是关于解决承诺不显示模板中的数据的主要内容,如果未能解决你的问题,请参考以下文章
Angular UI Modal 打开的承诺在显示模态之前解决
数据显示在 websocket 响应中,但未显示在已解决的承诺中
vCenter 6.0 升级到 vCenter 7.0 虚拟机模板库不显示解决