Ember选择承诺解决前的组件渲染

时间:2015-01-08 00:29:21

标签: ember.js ember-data ember-cli rsvp.js

我有一个组件可以为<select>标记添加一些功能。我希望在<select>完全呈现包括所有<option>标记之后初始化一些javascript。用于填充<option>标记的数据是从ajax请求提供的对象数组。

我正在使用ember-data,并且当从商店提供数据时发现这是有效的,这意味着它是DS.RecordArray的一个实例,它具有有用的属性,如isLoaded。但是,当数据是从jQuery ajax调用提供的并且只是普通的JSON时,看起来好像组件在jQuery返回的promise之前尝试渲染所有内容。

我觉得问题在于我如何处理承诺,因为这个问题似乎与他们应该开始之前的事情有关(即承诺已经正确解决)。我尝试在一个RSVP.Promise对象中包装ajax调用,但没有运气,(我正在使用Ember-CLI)。下面是我到目前为止的简化版本。任何帮助将不胜感激。

// My route
export default Ember.Route.extend({
    setupController: function(controller, model) {
        this._super(controller, model);

        var hash = Ember.RSVP.hash({
                // myOptions: $.getJSON('/api/options')
                myOptions: new Ember.RSVP.Promise(function(resolve, reject) {
                    Ember.$.ajax({
                        url: '/api/options',
                        type: 'get',
                        dataType: 'json',
                        success: function(result) {
                            Ember.run(null, resolve, result);
                        },
                        error: function(result) {
                            Ember.run(null, reject, result);
                        }
                    });
                })
            });

        return hash.then(function(result) {
            controller.set('optionsForSelect', result.myOptions);
        });
    }
});

// My component
export default Ember.Select.extend({
    didInsertElement: function() {
        // Is called before ajax request has finished
        this.$().mySelectPlugin({
        });
    }
});

// Handlebars template
{{my-select-plugin content=optionsForSelect optionValuPath="content.id" optionLabelPath="content.name"}}

1 个答案:

答案 0 :(得分:2)

对我而言,这似乎应该在控制器中处理,而不是路由。以下是我为类似情况所做的事情。

App.LessonsShowIndexController = Ember.ObjectController.extend({
    author: function() {
        return this.get('model').get('author');
    }.property('author'),
    fullName: function() {
        return this.get('author').get('firstName') + ' ' + this.get('author').get('lastName');
    }.property('author.isFulfilled'),
});

使用isFulfilled属性允许控制器在使用数据之前等待promise解析。在您的情况下,您可以拥有一个返回承诺的属性和另一个等待它完成的属性。