Ember.js Masonry渲染并不等待生成数据模型

时间:2014-05-28 19:43:10

标签: ember.js masonry

我正在尝试构建一个假想的电子商务网站中畅销商品的砖石视图,但是在通过RESTAdapter生成数据模型之前,正在渲染Masonry。这是我的Ember.js代码:

App.Userprofile = DS.Model.extend({
    loggedIn: DS.attr('boolean'),
    name: DS.attr('string'),
    totalItems: DS.attr('number'),
});

App.ApplicationRoute = Ember.Route.extend({

    setupController: function(controller) {
        this.store.find('userprofile', 'bat@man.com').then (function(userprofile) {
            controller.set ('model', userprofile);
        });
    }
});

App.ApplicationAdapter = DS.DjangoRESTAdapter.extend({
    host: HOST,
    namespace: 'api'
});

App.ApplicationView = Ember.View.extend({
    elementId: '',
    classNames: ['container','fullwidth'],
    templateName: 'application'
});

App.Cloud = DS.Model.extend({
    item: DS.attr('string'),
    numberItems: DS.attr('number'),
    rank: DS.attr('number')
});

App.CloudAdapter = DS.DjangoRESTAdapter.extend({
    host: HOST,
    namespace: 'api',
});

App.CloudController = Ember.ObjectController.extend({
    needs: ['application'],
    cloudSize: function() { // Determines the size of the div
        var cloudsize = Math.round (this.get('model.numberItems') * 5 / this.get('controllers.application.totalItems')) + 1;
        var divName = "score" + cloudsize.toString();
        return divName;
    }.property('model.numberItems', 'controllers.application.totalitems')
});

App.ItemcloudRoute = Ember.Route.extend({
    setupController: function(controller) {
        this.store.findAll('cloud').then (function(itemcloud) {
            controller.set ('model', itemcloud);
        });
    }
});

App.ItemcloudController = Ember.ArrayController.extend({
    needs: ['cloud', 'application'],
    sortProperties: ['rank'],
});

App.ItemcloudView = Ember.View.extend({
    elementId: 'magicgrid',
    classNames: ['cloudcontainer'],
    templateName: 'itemcloud',
    didInsertElement: (function() {
        this._super();
        Ember.run.scheduleOnce('afterRender', this, this.applyMasonry);
    }).observes('controller.itemcloud'),

    applyMasonry: function() {
        setTimeout( function() { // settimeout to ensure masonry is called after data models are generate
            console.log ("applyMasonry being called");
            $('#magicgrid').masonry({
                itemSelector: '.company',
                isAnimated: true
            });
        }, 2000);
    }
});

以下是模板文件中生成itemcloud的部分。

    <script type="text/x-handlebars" data-template-name='itemcloud'>
            {{#each controller.model itemController="cloud"}}

                <div {{bind-attr class=":company cloudSize"}}>
                    <div class="companylogo">
                        <img src="images/logos/color-logos/logo-01.jpg" />
                    </div>
                    <div class="count">{{numberItems}}</div>
                </div>
            {{/each}}
            <div class="clearfix"></div>
    </script>

现在,由于数据获取和模板渲染的异步性质,我很难找到一种方法来保存Masonry渲染,直到获取数据为止。我的研究表明,使用View for the CloudController对象会很有用,但我想弄清楚我当前设计中是否缺少某些东西。此外,如果有人可以为CloudController对象提供正确使用Views的指针

如果我需要提供更多说明,请与我们联系。谢谢!

1 个答案:

答案 0 :(得分:1)

如果您在setupController Ember中执行此操作,则假定模型已准备好并继续呈现页面,尽管响应未从服务器返回。

最简单的方法是在模型钩子中返回模型/承诺。 Ember将等待呈现页面,直到模型得到解决。

App.ItemcloudRoute = Ember.Route.extend({
    model: function(){   
        this.store.find('cloud');
    }
});

上面的代码将执行您的代码所做的相同操作,除非在控制器上创建和设置模型之前Ember会等待查找解析。

根据kingpin2k评论更新答案以反映工作代码:

 App.ApplicationRoute = Ember.Route.extend({
    model: function() {  
        return this.store.find ('userprofile', 'bat@man.com');  
    },  
    setupController: function(controller, model) {  
        controller.set ('model', model);  
    }  
});