承诺结果 Ember 数据计算 属性
Promise result in Ember Data computed property
我正在尝试调用外部 API 并将结果用作我的 Ember 数据模型中的计算结果 属性。结果被很好地获取,但是在 Promise 解析之前计算的 属性 returns 导致未定义。这是观察者的用例吗?
export default DS.Model.extend({
lat: DS.attr(),
lng: DS.attr(),
address: Ember.computed('lat', 'lng', function() {
var url = `http://foo.com/json?param=${this.get('lat')},${this.get('lng')}`;
var addr;
var request = new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax(url, {
success: function(response) {
resolve(response);
},
error: function(reason) {
reject(reason);
}
});
});
request.then(function(response) {
addr = response.results[0].formatted_address;
}, function(error) {
console.log(error);
})
return addr;
})
});
创建组件(地址-display.js):
import Ember from 'ember';
export default Ember.Component.extend({
init() {
var url = `http://foo.com/json?param=${this.get('lat')},${this.get('lng')}`;
Ember.$.ajax(url, {
success: function(response) {
this.set('value', response.results[0].formatted_address);
},
error: function(reason) {
console.log(reason);
}
});
}
});
模板(components/address-display.hbs):
{{value}}
然后在您的模板中使用该组件:
{{address-display lat=model.lat lng=model.lng}}
下面的工作是在 属性 内部解析并设置结果。
这里解释:
http://discuss.emberjs.com/t/promises-and-computed-properties/3333/10
export default DS.Model.extend({
lat: DS.attr(),
lng: DS.attr(),
address: Ember.computed('lat', 'lng', function() {
var url = `http://foo.com/json?param=${this.get('lat')},${this.get('lng')}`;
var self = this;
var request = new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax(url, {
success: function(response) {
resolve(response);
},
error: function(reason) {
reject(reason);
}
});
}).then(function(response) {
self.set('address', response.results[0].formatted_address);
})
})
});
我已经在大型 Ember 应用程序中使用 self.set('computed_property', value);
技术大约三个月了,我可以告诉你它有一个非常大的问题:计算的 属性 只会工作 一次.
当您 set
计算 属性 值时,生成结果的函数将丢失,因此当您的相关模型属性更改时,计算 属性 将不会刷新。
在 Ember 中的计算属性中使用 promises 很麻烦,我发现的最佳技术是:
prop: Ember.computed('related', {
// `get` receives `key` as a parameter but I never use it.
get() {
var self = this;
// We don't want to return old values.
this.set('prop', undefined);
promise.then(function (value) {
// This will raise the `set` method.
self.set('prop', value);
});
// We're returning `prop_data`, not just `prop`.
return this.get('prop_data');
},
set(key, value) {
this.set('prop_data', value);
return value;
}
}),
优点:
- 它适用于模板,因此您可以在模板中执行
{{object.prop}}
,它会正确解析。
- 它会在相关属性更改时更新。
缺点:
- 当你在 Javascript
object.get('prop');
中执行并且 promise 正在解决时,它会 return 你立即 undefined
,但是如果你正在观察计算 属性,当 promise 解析并设置最终值时,观察者将再次触发。
也许您想知道为什么我没有 return在 get
中做出承诺;如果你这样做并在模板中使用它,它将呈现一个对象字符串表示([object Object]
或类似的东西)。
我想在模板中运行良好的适当计算 属性 实现中工作,return Javascript 中的承诺并自动更新,可能使用类似 DS.PromiseObject or Ember.PromiseProxyMixin, 可惜我没时间。
如果大骗局对您的用例来说不是问题,请使用 "get/set" 技术,如果不是,请尝试实施更好的方法,但认真 不要只使用 self.set('prop', value);
,从长远来看会给你带来很多问题,不值得。
PS.:然而,这个问题真正的、最终的解决方案是:如果可以避免的话,永远不要在计算属性中使用 promises。
PS.:顺便说一下,这个技术不是我的,而是我的前同事@reset-reboot。
使用DS.PromiseObject。我一直使用以下技术:
import DS from 'ember-data';
export default DS.Model.extend({
...
address: Ember.computed('lat', 'lng', function() {
var request = new Ember.RSVP.Promise(function(resolve, reject) {
...
});
return DS.PromiseObject.create({ promise: request });
}),
});
在模板中使用已解析的值作为 {{address.content}}
,它将在代理的 Promise 解析时自动更新。
如果您想在这里做更多事情,我建议您查看社区中的其他人在做什么:https://emberobserver.com/?query=promise
构建一个简单的组件并不难.
我在我工作的应用程序中有一个 Ember.Service
,它几乎完全由 return 包裹在 DS.PromiseObjects 中的计算属性组成。它运行起来非常顺畅。
我正在尝试调用外部 API 并将结果用作我的 Ember 数据模型中的计算结果 属性。结果被很好地获取,但是在 Promise 解析之前计算的 属性 returns 导致未定义。这是观察者的用例吗?
export default DS.Model.extend({
lat: DS.attr(),
lng: DS.attr(),
address: Ember.computed('lat', 'lng', function() {
var url = `http://foo.com/json?param=${this.get('lat')},${this.get('lng')}`;
var addr;
var request = new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax(url, {
success: function(response) {
resolve(response);
},
error: function(reason) {
reject(reason);
}
});
});
request.then(function(response) {
addr = response.results[0].formatted_address;
}, function(error) {
console.log(error);
})
return addr;
})
});
创建组件(地址-display.js):
import Ember from 'ember';
export default Ember.Component.extend({
init() {
var url = `http://foo.com/json?param=${this.get('lat')},${this.get('lng')}`;
Ember.$.ajax(url, {
success: function(response) {
this.set('value', response.results[0].formatted_address);
},
error: function(reason) {
console.log(reason);
}
});
}
});
模板(components/address-display.hbs):
{{value}}
然后在您的模板中使用该组件:
{{address-display lat=model.lat lng=model.lng}}
下面的工作是在 属性 内部解析并设置结果。
这里解释: http://discuss.emberjs.com/t/promises-and-computed-properties/3333/10
export default DS.Model.extend({
lat: DS.attr(),
lng: DS.attr(),
address: Ember.computed('lat', 'lng', function() {
var url = `http://foo.com/json?param=${this.get('lat')},${this.get('lng')}`;
var self = this;
var request = new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax(url, {
success: function(response) {
resolve(response);
},
error: function(reason) {
reject(reason);
}
});
}).then(function(response) {
self.set('address', response.results[0].formatted_address);
})
})
});
我已经在大型 Ember 应用程序中使用 self.set('computed_property', value);
技术大约三个月了,我可以告诉你它有一个非常大的问题:计算的 属性 只会工作 一次.
当您 set
计算 属性 值时,生成结果的函数将丢失,因此当您的相关模型属性更改时,计算 属性 将不会刷新。
在 Ember 中的计算属性中使用 promises 很麻烦,我发现的最佳技术是:
prop: Ember.computed('related', {
// `get` receives `key` as a parameter but I never use it.
get() {
var self = this;
// We don't want to return old values.
this.set('prop', undefined);
promise.then(function (value) {
// This will raise the `set` method.
self.set('prop', value);
});
// We're returning `prop_data`, not just `prop`.
return this.get('prop_data');
},
set(key, value) {
this.set('prop_data', value);
return value;
}
}),
优点:
- 它适用于模板,因此您可以在模板中执行
{{object.prop}}
,它会正确解析。 - 它会在相关属性更改时更新。
缺点:
- 当你在 Javascript
object.get('prop');
中执行并且 promise 正在解决时,它会 return 你立即undefined
,但是如果你正在观察计算 属性,当 promise 解析并设置最终值时,观察者将再次触发。
也许您想知道为什么我没有 return在 get
中做出承诺;如果你这样做并在模板中使用它,它将呈现一个对象字符串表示([object Object]
或类似的东西)。
我想在模板中运行良好的适当计算 属性 实现中工作,return Javascript 中的承诺并自动更新,可能使用类似 DS.PromiseObject or Ember.PromiseProxyMixin, 可惜我没时间。
如果大骗局对您的用例来说不是问题,请使用 "get/set" 技术,如果不是,请尝试实施更好的方法,但认真 不要只使用 self.set('prop', value);
,从长远来看会给你带来很多问题,不值得。
PS.:然而,这个问题真正的、最终的解决方案是:如果可以避免的话,永远不要在计算属性中使用 promises。
PS.:顺便说一下,这个技术不是我的,而是我的前同事@reset-reboot。
使用DS.PromiseObject。我一直使用以下技术:
import DS from 'ember-data';
export default DS.Model.extend({
...
address: Ember.computed('lat', 'lng', function() {
var request = new Ember.RSVP.Promise(function(resolve, reject) {
...
});
return DS.PromiseObject.create({ promise: request });
}),
});
在模板中使用已解析的值作为 {{address.content}}
,它将在代理的 Promise 解析时自动更新。
如果您想在这里做更多事情,我建议您查看社区中的其他人在做什么:https://emberobserver.com/?query=promise
构建一个简单的组件并不难.
我在我工作的应用程序中有一个 Ember.Service
,它几乎完全由 return 包裹在 DS.PromiseObjects 中的计算属性组成。它运行起来非常顺畅。