Javascript “在”上等待EmberJS中的属性;服务器";一边

Javascript “在”上等待EmberJS中的属性;服务器";一边,javascript,ember.js,handlebars.js,Javascript,Ember.js,Handlebars.js,在Ember中,可以引用模板中的属性,模板将在渲染之前等待填充该属性 这对于获取由外部REST端点填充的条目列表非常有用: App.ItemsListRoute = Ember.Route.extend({ model: function() { return { client: App.Client.create() } } }); 其中客户端构造函数看起来像: App.Client = Ember.Object.ext

在Ember中,可以引用模板中的属性,模板将在渲染之前等待填充该属性

这对于获取由外部REST端点填充的条目列表非常有用:

App.ItemsListRoute = Ember.Route.extend({
    model: function() {
        return {
            client: App.Client.create()
        }
    }
});
其中客户端构造函数看起来像:

App.Client = Ember.Object.extend({
    init: function() {
        var _this = this; // For referencing in AJAX callback
        $.ajax({
            url: MY_API_URL,
            type: 'GET'
        }).done(function(res) {
            _this.set('itemsList', parsedDataFromRes);
        });
    },
});
对于依赖于
itemsList
的模板,这非常有用:

...
{{#each item in model.client.itemsList}}
      <tr>
...
我意识到这是一个做作的例子——我可以在模板上查询
长度
,它会工作得很好——但你必须幽默我

上述示例的问题在于,
get('itemsList')
可能会返回一个未定义的值,这是基于呈现模板的数据竞争以及调用的AJAX响应和属性设置器

我如何“等待”属性在我的JS(不是模板代码)中变为可用,以便它可以用于为模板提供模型


'itemsList'
属性转换为返回承诺的函数是否是最“类似余烬”的方法?这会使我的模板逻辑变得非常复杂吗?

您可以在
函数调用中使用承诺并执行附加操作。
比如你能做什么

App.StatsPageRoute = Ember.Route.extend({
    model: function() {
        var itemCount = getClient().then(function(promiseResult){
           var itemCount = promiseResult.get('itemsList').length;
           return {
            numItems: itemCount
          }
        })
})
然而,要使用它,您需要确保getClient返回一个承诺。我建议您使用
icajax
(包含在Ember中)。它是对jquery
ajax
的抽象,它返回承诺,而不是期望成功和错误的回调

此外,我强烈建议您研究
ember数据
,并尝试构建一个符合规范的后端。这样,您的数据就有了一个很好的抽象,它极大地提高了开发速度,因为您不必担心与后端的交互


编辑:返回承诺而不是数据不会影响模板逻辑。Ember将解析承诺,当值更改时,Ember运行循环将自动更新模板。不过,您可能希望有一个默认值或某种微调器。然而,不管您的模型是否返回承诺,这可能是您应该做的事情。

如果我更改
getClient()
函数以返回承诺,这会如何改变我模板页面上的逻辑?@CraigOtis,我更新了我的帖子来回答您的问题。不要犹豫,要求更多的澄清。
App.StatsPageRoute = Ember.Route.extend({
    model: function() {
        var itemCount = getClient().then(function(promiseResult){
           var itemCount = promiseResult.get('itemsList').length;
           return {
            numItems: itemCount
          }
        })
})