I'm trying to access a model's method from within an .eco template using backbone/marionette.js. I have an Expense
model with a day()
method which, using moment.js, returns '13th'; for example:
class Expense extends Backbone.Model
day: ->
moment.get('date').format('Do')
I can create a new Expense
as follows, and call the day()
method:
coffee = new Expense({name: "Coffee", amount: 2.50, date: "2014-01-13T13:50:00Z"})
coffee.day() # 13th
However, trying to access day()
from within the following view and template is causing me some problems:
class ExpenseView extends Marionette.ItemView
template: "views/_expense"
# views/_expense.jst.eco
<h3 class="expense__name"><%= @name %></h3>
<p class="expense__day"><%= @day() %></p>
I understand why it isn't working...the ItemView
calls serializeData
which returns @model.toJSON()
... therefore, the Expense
's day()
method isn't accessible. Is there an established pattern in the backbone/marionette community that makes model methods available to templates?
So far, I've done the following to make it work:
class ExpenseView extends Marionette.ItemView
template: "views/_expense"
serializeData: ->
_.extend(@model.toJSON(), model: @model)
templateHelpers:
day: ->
@model.day()
But I'm unsure whether this is the best way to go about the problem? Thanks!
You can always add it to templateHelpers
or serializeData
- but what you're really asking about is a virtual attribute - one that can be part of every template, an attribute that is used solely as part of a ViewModel
. In this way we can also disable it from syncing to the server on sync
events such as save()
There are several plugins out there that do this, my personal favorite to use is Backbone Mutators
- https://github.com/asciidisco/Backbone.Mutators
Others like Backbone Computed Fields
- https://github.com/alexanderbeletsky/backbone-computedfields give you Ember like computed properties.
With Backbone Mutators you would write your mutators in the Backbone Model.
class Model extends Backbone.Model
mutators:
day: ->
moment.get('date').format('Do')
Alternatively to prevent the 'day' attribute from syncing to the backend...
class Model extends Backbone.Model
mutators:
day:
get: -> moment.get('date').format('Do')
transient: true
The day
attribute will be present in all toJSON()
calls now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With