最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to access Backbone.Model methods from Marionette.js ItemView template? - Stack Overflow

programmeradmin0浏览0评论

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 munity 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!

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 munity 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!

Share Improve this question edited Jan 13, 2014 at 14:14 danscotton asked Jan 13, 2014 at 14:08 danscottondanscotton 534 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 8

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./asciidisco/Backbone.Mutators

Others like Backbone Computed Fields - https://github./alexanderbeletsky/backbone-putedfields give you Ember like puted 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.

Why don't you just add it to serializeData ? (Can't remember Coffee syntax...)

serializeData: function(){
    var data = _.clone(this.model.attributes);
    data.day = this.model.day();
    return data;
}
发布评论

评论列表(0)

  1. 暂无评论