web-dev-qa-db-fra.com

Façon appropriée de faire des mixins de vue dans Backbone

J'étends les vues de base de base tout le temps et j'ai une vue de base par section afin de pouvoir étendre sur plusieurs niveaux. Ma question est la suivante: quel est le moyen le plus efficace de faire des mixins de vue: des partiels de vue réutilisables qui peuvent être mélangés à n'importe quelle vue. Par exemple:

var BaseProfile = Backbone.View.extend({ ...});
var UserProfile = BaseProfile.extend({ ...});
var VideoSupport = Backbone.View.extend({ ...});

Quelle est la meilleure façon de mélanger la vue VideoSupport (un objet événement et quelques méthodes) avec la vue UserProfile?

58
Mauvis Ledford

La bibliothèque underscore.js fournit une méthode extend qui fait ce que vous voulez. Vous pouvez définir des fonctionnalités sur n'importe quel objet, puis copier et coller littéralement toutes les méthodes et tous les attributs de cet objet vers un autre.

Les méthodes extend de Backbone sur les vues, les modèles et les routeurs sont un wrapper autour du extend du soulignement.

 var MyMixin = {
  foo: "bar",
  sayFoo: function(){alert(this.foo);}
}

var MyView = Backbone.View.extend({
 // ...
});

_.extend(MyView.prototype, MyMixin);

myView = new MyView();
myView.sayFoo(); //=> "bar"
111
Derick Bailey

Je pourrais recommander d'utiliser Backbone.Cocktail qui fournit un moyen vraiment succinct de spécifier les mixins (qui respectent l'héritage):

var Mixin = {
  initialize: function() {
    console.log("I'll be called as well as the class's constructor!");
  }
};

var View = Backbone.View.extend({
  mixins: [ MyMixin ]
});

Je l'ai détaillé dans ce article de blog .

19
Dan S

vous pouvez utiliser ce Gist https://Gist.github.com/3652964

3
user873792

Vous pouvez utiliser bibliothèque Backbone.Mix qui utilisait des mixins intégrés à la chaîne prototype

var Editable = {
    edit: function(){
        console.log('edit');
    }
};

var Article = Backbone.Model.mix(Editable).extend({
    initialize: function(){
        Backbone.Model.prototype.initialize.call(this);
        this.edit(); // logs "edit"
    }
});
3
jifeon

J'avais besoin de la capacité de remplacer et d'appeler des méthodes mixtes (ala super) plus près de la façon dont Ruby gère les modules. Et la méthode d'extension simple encombrerait la méthode mixin si elle existait dans la classe. Puisque je Je construis tout cela dans CoffeeScript J'ai accès à l'objet super qui me permet de shimer les méthodes. Il fusionnera également automatiquement l'objet événements afin que vous puissiez définir des gestionnaires d'événements dans le mixin.

_.extend Backbone,
  mixin: (klass, mixin, merge) ->
    debugger unless mixin
    mixin = mixin.prototype || mixin
    merge ||= ["events"]

    sup = _.extend({},klass.__super__)

    for name,func of mixin      
      if base = sup[name] && _.isFunction(base)
        sup[name] = ->
          func.apply this, arguments
          base.apply this, arguments
      else
        sup[name] = func

    hp = {}.hasOwnProperty
    prototype = klass.prototype
    for name,func of mixin
      continue unless hp.call(mixin,name)
      continue if _(merge).contains name
      prototype[name] = func unless prototype[name]

    klass.__super__ = sup

    _(merge).each (name) ->
      if mixin[name]
        prototype[name] = _.extend({},mixin.events,prototype.events) 

    @

Usage

class SimpleView extends Backbone.View
  events:
    "click .show" : "show"

  calculate: ->
    super + 5

  show: ->
    console.log @calculate()

class CalculatableViewMixin
  events:
    "click .calculate" : "show"

  calculate: ->
    15

Backbone.mixin SimpleView, CalculatableViewMixin
2
Paul Alexander

Une autre option est le Backbone.Advice qui fournit la puissance des mixins de style AOP (vous pouvez injecter un comportement personnalisé avant , après ou autour de appels de méthodes d'objets étendus).

1
ipbd