如何从 Marionette.js ItemView 模板访问 Backbone.Model 方法?
Posted
技术标签:
【中文标题】如何从 Marionette.js ItemView 模板访问 Backbone.Model 方法?【英文标题】:How to access Backbone.Model methods from Marionette.js ItemView template? 【发布时间】:2014-02-01 07:35:36 【问题描述】:我正在尝试使用主干/marionette.js 从 .eco 模板中访问模型的方法。我有一个带有day()
方法的Expense
模型,该方法使用moment.js 返回'13th';例如:
class Expense extends Backbone.Model
day: ->
moment.get('date').format('Do')
我可以如下新建Expense
,并调用day()
方法:
coffee = new Expense(name: "Coffee", amount: 2.50, date: "2014-01-13T13:50:00Z")
coffee.day() # 13th
但是,尝试从以下视图和模板中访问 day()
会给我带来一些问题:
class ExpenseView extends Marionette.ItemView
template: "views/_expense"
# views/_expense.jst.eco
<h3 class="expense__name"><%= @name %></h3>
<p class="expense__day"><%= @day() %></p>
我理解为什么它不起作用...ItemView
调用 serializeData
返回 @model.toJSON()
...因此,Expense
的 day()
方法是'不可访问。骨干/牵线木偶社区中是否存在使模型方法可用于模板的既定模式?
到目前为止,我已经完成了以下工作:
class ExpenseView extends Marionette.ItemView
template: "views/_expense"
serializeData: ->
_.extend(@model.toJSON(), model: @model)
templateHelpers:
day: ->
@model.day()
但我不确定这是否是解决问题的最佳方法?谢谢!
【问题讨论】:
【参考方案1】:您始终可以将其添加到 templateHelpers
或 serializeData
- 但您真正要问的是一个虚拟属性 - 可以成为每个模板的一部分,一个仅用作 @ 一部分的属性987654325@。通过这种方式,我们还可以在sync
事件(例如save()
)上禁用它与服务器同步
有几个插件可以做到这一点,我个人最喜欢使用的是Backbone Mutators
- https://github.com/asciidisco/Backbone.Mutators
像 Backbone Computed Fields
- https://github.com/alexanderbeletsky/backbone-computedfields 这样的其他人会为您提供类似 Ember 的计算属性。
使用 Backbone Mutators,您可以在 Backbone 模型中编写您的 mutators。
class Model extends Backbone.Model
mutators:
day: ->
moment.get('date').format('Do')
或者防止'day'属性同步到后端...
class Model extends Backbone.Model
mutators:
day:
get: -> moment.get('date').format('Do')
transient: true
day
属性现在将出现在所有 toJSON()
调用中。
【讨论】:
感谢 Brian,我非常喜欢这个 Backbone.Mutators 插件!我喜欢它如何将逻辑从我的视图中移到模型中——有点像 Rails 中的 :scope。transient: true
也是一个不错的补充!【参考方案2】:
你为什么不把它添加到 serializeData
? (不记得 Coffee 语法了……)
serializeData: function()
var data = _.clone(this.model.attributes);
data.day = this.model.day();
return data;
【讨论】:
谢谢大卫,我在想也许重写Expense
的toJSON
方法会更好...这样逻辑被封装在模型而不是视图中?
问题是如果你将它添加到toJSON
它也会被发送到 API 端点,这可能是一个问题。
啊,我明白了。也许我可以在所有Marionette.View
s 中扩展serializeData
,这样它就会调用一个新方法toData
(或更好的名称),如果它存在的话,否则就照常调用toJSON
。然后我可以选择在我的任何模型中实现toData
以将模型属性与我选择的任何自定义属性合并?
这是可能的。或者使用您要添加的额外参数定义一个 extendJSON
方法。然后在 Marionette 的serailzeData
中,您只需将_.extend
添加extendJSON
的结果返回的正常值(如果定义了extendJSON
)。这样可以避免代码重复。以上是关于如何从 Marionette.js ItemView 模板访问 Backbone.Model 方法?的主要内容,如果未能解决你的问题,请参考以下文章
Marionette.js 与 Chaplin.js 的比较