简体   繁体   中英

Looking for guidance on MVC in Backbone.js

According to MVC, models are a "pure" data representation. You don't want presentational or non-DRY data in there. For example if your model has a "comment_count" field, it shouldn't also contain a "use_plural" field so that you can know whether to print "comment" or "comments".

This post has 0 comments
This post has 1 comment
This post has 2 comments
...

If you put that info in the model, it's bad separation of concerns, however, the alternative is to derive that info in the view. For example:

var FooView = Backbone.View.extend({
  render: function(){
    this.data = this.model.toJSON();
    this.data.use_plural = this.data.comment_count === 1;
    // and fifty more lines like the above
    $(this.el).html(ich['foo_template'](this.data));
  }
});

My question is, there seems to be this need for in-between data that's too view-ish to be part of the model, but too model-ish to be part of the view. Is that what MVVM addresses? I looked that up but it seemed very Microsoft-tech-stack-specific. I was thinking of putting it into a function and calling it from within render() methods:

function deriveData(model){
  var data = model.toJSON();
  data.use_plural = data.comment_count === 1;
  // and fifty more lines like the above
  return data;
}

var FooView = Backbone.View.extend({
  render: function(){
    this.data = deriveData(this.model);
    $(this.el).html(ich['foo_template'](this.data));
  }
});

var BarView = Backbone.View.extend({
  render: function(){
    this.data = deriveData(this.model);
    $(this.el).html(ich['bar_template'](this.data));
  }
});

Another idea was to have an AbstractView class and inherit from it, like so:

var AbstractView = Backbone.View.extend({
  deriveData: function(){
    this.data = this.model.toJSON();
    this.data.use_plural = this.data.comment_count === 1;
    // and fifty more lines like the above
  }
});

var FooView = AbstractView.extend({
  render: function(){
    this.deriveData();
    $(this.el).html(ich['foo_template'](this.data));
  }
});

var BarView = AbstractView.extend({
  render: function(){
    this.deriveData();
    $(this.el).html(ich['bar_template'](this.data));
  }
});

It's not so much that I'm stumped, I just want to make sure I'm not floating along in ignorance while there's this awesome methodology out there that addresses this exact question. Does anyone have any recommendations or thoughts, or are there well-established patterns I could leverage here? Thanks.

This is a personal opinion (even if it comes from long experience and is shared by many), so take it with a grain of salt.

The MVC pattern just doesn't fit the web really well. And the problem always seem to lie in the Controller . Lots of people who've been around for a while know that and accept it silently. Most frameworks use the term MVC as a classification because well, it's convenient to explain in pattern terms what the framework aims at and also most other comparable frameworks use the term.

If you really need to attach a meaning to who is the View and who is the Controller in Backbone, most people think they are both the View. Views generate the template but also dispatch events from the UI to the model and vice-versa. If you really really need to keep them separate, you can also think that View classes are Controllers and the templates are the Views .

Hopefully you get the idea: it does not matter what you call it . It matters though how you use it.

Concerning the practical part of your question: I would use any of these depending on the context. Is it something small you use once? Do it inside render . Is it some logic that happens to be part of your View architecture and is needed in multiple views? Derive from a base class. Same way you do with everything else.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM