Ember绑定模型到模板

时间:2014-10-07 09:13:11

标签: ember.js ember-data

我很难理解在Ember中将模型绑定到模板的不同方法,以及何时使用其中一种模式。

遵循不同的教程我的代码应该可以工作,但它没有。 cal.hbs

<div class="calendar">
    {{#each cal}}
        {{#if days_label.length}}
            {{days_label.[1]}}
        {{/if}}
        {{test}}
    {{/each}}

</div>

cal_model.js

WebCalendar.Cal = DS.Model.extend({
    today: DS.attr('date'),
    test: DS.attr('number'),
    days_label: DS.attr('array'),
    months_label: DS.attr('array'),
    days_per_month: DS.attr('array')

});


WebCalendar.Cal.FIXTURES = [{   
        id: 1,
        test: 2,
        today: new Date(),
        days_label: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],

        months_label: ['January', 'February', 'March', 'April',
                         'May', 'June', 'July', 'August', 'September',
                         'October', 'November', 'December'],

        days_per_month: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
}];

Router.js

WebCalendar.CalRoute = Ember.Route.extend({
    model: function(){
        return this.store.find('cal');
    }
});

cal_controller.js

WebCalendar.CalController = Ember.ArrayController.extend({
    month: function(){
        var today = this.get('test');
        return today + 1;
    }.property('model'),

    monthCal: function(year, month){
        var today = this.store.find('cal', { today: new Date() });
        this.year = today.getFullYear();
        this.month = today.getMonth();
    },


    updateContent: function() { //doesn't work if is called arrangedContent
        return this.get('model').content;
    }.property('model')
});

根据我的理解,有以下方法来挂钩模型: 第一

<div class="calendar">
    {{#each cal}}
        {{#if days_label.length}}
            {{days_label.[1]}}
        {{/if}}
        {{test}}
    {{/each}}

</div>

第二

<div class="calendar">
    {{#each cal in controller}}
        {{#if days_label.length}}
            {{days_label.[1]}}
        {{/if}}
        {{test}}
    {{/each}}

</div>

第三

<div class="calendar">
    {{#each item in arrangedContent}} //this work if I don't specify arrangedContent in my controller
        {{#if item.days_label.length}}//this doesn't work
            {{item.days_label.[1]}}//this doesn't work
        {{/if}}
        {{item.test}}// this works
    {{/each}}

</div>

我想要理解的是,我找不到好的解释是:这些方式之间的区别是什么,什么时候使用什么,什么是什么,以及排列的内容

非常感谢您的任何解释!

1 个答案:

答案 0 :(得分:1)

ArrangedContent,如果我没错,是一个由...生成的数组 EMBER.SORTABLEMIXIN CLASS现在默认情况下已EMBER.ARRAYPROXY CLASS实施,因此您的数组控制器会继承arrangedcontent property

实际上是一个数组,它是您控制器的内容,按照您在控制器中定义的属性(sortProperties, sortAscending)进行排序。

因此,如果我有控制器内容(具有属性名称的对象数组),我可以选择按名称属性对其进行排序(sortProperties:[&#39; name&#39;],从而呈现它们按字母顺序升序(sortAscending:true)。

第一个和第二个问题之间的区别在于循环内部作为当前对象传递的内容。

首先,您将致电{{days_label}}以获取与this.days_label相同的days_label。

在您的第二个示例中,虽然您可以拨打{{days_label}},但也可以致电cal.days_label,但在两种情况下都是相同的,但如果您让我们说更深入则需要它在迭代中,如:

  

{{#controller in controller}}

   {{#if days_label.length}}
       {{#each day in days_label}}
           {{day.someProperty}}
           {{days_label.someOtherProperty}}
        {{/each}}

   {{/if}}
   {{test}}
     

{{/每}}

在这个示例中,我可以{{#each controller}}{{#each days_label}}内,然后在其中执行{{someProperty}},但之后我无法为{{days_label.someOtherProperty}}执行此操作{1}}因为this会发生变化。

要考虑的另一件事(在使用ember数据时非常有用)是模型与控制器内容之间的差异。 内容在路线setupController (controller, model)内设置,但可以覆盖。

更新

  

再次感谢您的回答:)对,现在代码有点乱,但我现在尝试实现的非常简单。有了我的模型,我想显示当前月份。我试着今天采取&#39;从我的模型,在我的控制器中,执行today.getMonth()并保存为属性(月),所以我应该能够在{{month}}的hbs中显示。 - Giorgia Sambrotta

然后我会做的是从模型中的控制器移动逻辑。 关于ember数据的一些基本要点是调用this.store.find('resourceName'),向api的resoure索引路由发出请求,从而返回一个对象数组。 每次访问此路由时都会触发此调用,因为当您的服务器上的记录已更改时,ember是不可知的。

因此,假设您获得的对象数组中都包含某种日期,并且您只想从中获取月份,则可以在WebCalendar.Cal模型中定义计算属性。

内部WebCalendar.Cal

  month: (function() {
    var today = this.get('today');
    //do something to get the value you want here
  }).property('today')

要考虑的另一件事是,由于months_labeldays_labeldays_per_month是静态数组,因此您不需要在每条记录中传递它们,而是将它们移到您的内部模型,作为属性。

现在我们已经将逻辑移到模型中,您可以在itteration中调用{{month}},这将为您提供模型计算属性的结果。此外,如果今天卡尔记录发生变化,您将立即得到该更改。

你不想这样做的唯一原因是你不希望这个月属性在除了这个特定控制器之外的任何地方。 在这种情况下,你会去

在WebCalendar.CalController内部

setMonthToEachCal: function(){
   this.get('content').forEach(function(cal) { 
     today = cal.get('today');
     //prepare the month value here and set it in month var
     cal.set('month', month);
   });
}.observes('content.@each.today'),