在Ember.js中装饰相关模型的数据

时间:2015-02-17 16:43:53

标签: ember.js ember-data

我有一个Property模型和一个Pricing Summary模型,它们彼此相关,如下所示:

App.Property = DS.Model.extend({
    totalRoomCount: DS.attr(),
    name: DS.attr(),
    address: DS.attr(),
    city: DS.attr(),
    state: DS.attr(),
    zip: DS.attr(),
    pricingSummaries: DS.hasMany('pricingSummary', {async: true})
});

App.PricingSummary = DS.Model.extend({
    startDate: DS.attr(),
    endDate: DS.attr(),
    days: DS.hasMany('day', {async: true}),
    property: DS.belongsTo('property', {async: true})
});

在我的Property路由中,我将模型设置为Property,然后在模板中,我想输出与PricingSummary相关的Property列表},如下:

{{#each pricingSummary in pricingSummaries}}

{{render 'summaryRow' pricingSummary}}

{{/each}}

这很有效,我可以输出PricingSummary模板中每个特定summaryRow的属性,例如startDateendDate。但我真正想要做的是修改/格式化startDate并输出这个格式化的版本。基本上我认为我现在想要一个控制器,但我不知道如何将控制器与输出的特定定价摘要模型联系起来。

我该怎么做?此外,你可以看到PricingSummary也与我的Day模型有关系,所以我想要再次这样做,这是另一个层次。

请帮忙!

1 个答案:

答案 0 :(得分:0)

有几种方法可以实现这一点,而且所有这些方法都相对简单。

关于实际装饰模型,最简单的方法是在模型本身上创建计算属性。有些人不喜欢这样,因为他们认为模型应该是瘦的,装饰者应该在控制器/组件中,但这完全取决于您的喜好。你可以这样做:

App.YourModel = DS.Model.extend({
  date: attr('date'),
  formattedDate: function() {
    var date = this.get('date');
    return date ? this.get('date').toDateString() : null ; // Use your own format :-)
  }.property('date')
});

或者,我喜欢使用getter / setter模式,因此您可以使用双向绑定,它会将值封装到set上的日期或get上的字符串。在以下示例中,我使用moment.js来解析/格式化:

App.YourModel = DS.Model.extend({
  date: attr('date'),
  dateMarshal: function(key, value) {
    if (arguments.length > 1) {
      var parsed = moment(value);
      this.set('date', parsed.isValid() ? parsed.toDate() : null);
    }
    return this.get('date') ? moment(this.get('date')).format('MM/DD/YYYY') : null ;
  }.property('date'),
});

另一种选择是为itemController助手提供{{#each}}属性,但这与使用渲染无关,而不必使用自定义视图。

如果您在定价摘要行使用更多属性和某些操作(例如删除它),我的偏好是使用组件:

{{#each pricingSummary in pricingSummaries}}
  {{pricing-summary-item content=pricingSummary}}
{{/each}}

你的组件:

App.PricingSummaryItem = Ember.Component.extend({
  content: null,
  dateFormatted: function() {
    var formattedDate = this.get('content.date');
    // Format your date
    return formattedDate;
  }.property('content.date')
  actions: {
    'delete': function() {
      this.get('content').deleteRecord();
    },
    markRead: function() {
      this.set('content.isRead', true);
      this.get('content').save();
    }
  }
});

最后,为了解决日期问题而不是装饰,我会做一个绑定帮助。同样,此示例使用moment.js(我也使用ember-cli,因此请原谅ES6语法):

import Ember from 'ember';

export function formatDate(input, options) {
  input = moment(input);
  if (options.hashContexts.fromNow) {
    return input.fromNow();
  } else {
    return input.format(options.hash.format || 'LL');
  }
}

export default Ember.Handlebars.makeBoundHelper(formatDate);

然后您只需在模板中使用{{format-date yourDateProperty}}