解决承诺不在模板中显示数据
Resolving promise doesn't show data in template
我已经尝试了几次 versions/attempts 创建和 return 一个 RSVP.Promise
作为我模板的参数。
所有 console.log 都给出了合理的值,因此承诺 正在 解决。
我遇到的问题(这也是问题)是如何return将值解析为我的模板。
以下是我试过的版本:
// 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)渲染到
TestB
testB: [object Object]
testB.length:
虽然我会expect/want他们展示
TestB
<DS.PromiseObject:ember1117>
BB-Promotion
testB: <DS.PromiseObject:ember1117>
testB.length: 1
我知道有一些解决方法(我可以在解析 f.e 时设置另一个 属性),但我想以正确的方式进行操作并学习如何操作。
而且我知道,这些例子没有多大意义。这只是基本功能,一旦我得到这个,它会得到增强 运行.
首先请避开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 模板不支持 promise。所以你有三个选择:
- 只是不要这样做。通常你可以使用路由
model
钩子来做异步工作。
- 使用模板中的类似
ember-promise-helpers
的内容。
- 不要只是return一个承诺。
如果你做不到 1,我建议你做 3。为此你需要了解 PromiseProxyMixin
. In ember-data
you have two implementations for this Mixin, the PromiseArray
and PromiseObject
所有 ember-data
方法,例如 findAll
、findRecord
、query
或异步关系 return a 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
将是一个空的 array/unresolved 承诺,但是当承诺解决时,数组会更新,并且 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 失败,您将不会获得任何信息!
我已经尝试了几次 versions/attempts 创建和 return 一个 RSVP.Promise
作为我模板的参数。
所有 console.log 都给出了合理的值,因此承诺 正在 解决。 我遇到的问题(这也是问题)是如何return将值解析为我的模板。
以下是我试过的版本:
// 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)渲染到
TestB
testB: [object Object]
testB.length:
虽然我会expect/want他们展示
TestB
<DS.PromiseObject:ember1117>
BB-Promotion
testB: <DS.PromiseObject:ember1117>
testB.length: 1
我知道有一些解决方法(我可以在解析 f.e 时设置另一个 属性),但我想以正确的方式进行操作并学习如何操作。 而且我知道,这些例子没有多大意义。这只是基本功能,一旦我得到这个,它会得到增强 运行.
首先请避开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 模板不支持 promise。所以你有三个选择:
- 只是不要这样做。通常你可以使用路由
model
钩子来做异步工作。 - 使用模板中的类似
ember-promise-helpers
的内容。 - 不要只是return一个承诺。
如果你做不到 1,我建议你做 3。为此你需要了解 PromiseProxyMixin
. In ember-data
you have two implementations for this Mixin, the PromiseArray
and PromiseObject
所有 ember-data
方法,例如 findAll
、findRecord
、query
或异步关系 return a 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
将是一个空的 array/unresolved 承诺,但是当承诺解决时,数组会更新,并且 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 失败,您将不会获得任何信息!