装饰 Ember.js 中相关模型的数据
Decorating data from related model in Ember.js
我有一个 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
,然后在模板中,我想输出相关的 PricingSummary
列表那个Property
,如下:
{{#each pricingSummary in pricingSummaries}}
{{render 'summaryRow' pricingSummary}}
{{/each}}
这行得通,我能够在 summaryRow
模板中输出每个特定 PricingSummary
的属性,例如它的 startDate
和 endDate
,因为例子。但我在这里真正想做的是 modify/format startDate
并输出这个格式化版本。基本上我想此时我需要一个控制器,但我不知道如何将控制器绑定到正在输出的特定定价摘要模型。
我该怎么做?此外,您可以看到 PricingSummary
也与我的 Day
模型有关系,所以我想再做一次,另一个层次。
请帮忙!
有几种方法可以实现这一点,而且都比较简单。
关于实际装饰模型,最简单的方法是在模型本身上创建计算 属性。有些人不喜欢这样,因为他们认为模型应该很瘦,装饰器应该在 controllers/components 中,但这完全取决于您的喜好。你可以这样完成它:
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 模式,这样您就可以使用双向绑定,它会将值编组为设置的日期,或编组为获取的字符串。在下面的示例中,我使用 moment.js
到 parse/format:
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'),
});
另一种选择是向 {{#each}}
帮助程序提供 itemController
属性,但这实际上与使用渲染相同,而无需使用自定义视图。
如果您要使用更多属性并且可能对定价摘要行执行一些操作(例如删除它),我的首选是使用一个组件:
{{#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}}
。
我有一个 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
,然后在模板中,我想输出相关的 PricingSummary
列表那个Property
,如下:
{{#each pricingSummary in pricingSummaries}}
{{render 'summaryRow' pricingSummary}}
{{/each}}
这行得通,我能够在 summaryRow
模板中输出每个特定 PricingSummary
的属性,例如它的 startDate
和 endDate
,因为例子。但我在这里真正想做的是 modify/format startDate
并输出这个格式化版本。基本上我想此时我需要一个控制器,但我不知道如何将控制器绑定到正在输出的特定定价摘要模型。
我该怎么做?此外,您可以看到 PricingSummary
也与我的 Day
模型有关系,所以我想再做一次,另一个层次。
请帮忙!
有几种方法可以实现这一点,而且都比较简单。
关于实际装饰模型,最简单的方法是在模型本身上创建计算 属性。有些人不喜欢这样,因为他们认为模型应该很瘦,装饰器应该在 controllers/components 中,但这完全取决于您的喜好。你可以这样完成它:
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 模式,这样您就可以使用双向绑定,它会将值编组为设置的日期,或编组为获取的字符串。在下面的示例中,我使用 moment.js
到 parse/format:
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'),
});
另一种选择是向 {{#each}}
帮助程序提供 itemController
属性,但这实际上与使用渲染相同,而无需使用自定义视图。
如果您要使用更多属性并且可能对定价摘要行执行一些操作(例如删除它),我的首选是使用一个组件:
{{#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}}
。