Правильный способ сделать вид миксины в позвоночнике


Я постоянно расширяю базовые виды магистрали и имею базовый вид на секцию, чтобы я мог расширяться на нескольких уровнях. Мой вопрос в том, что является наиболее эффективным способом создания миксинов представления: многоразовые частичные представления, которые могут быть смешаны с любым представлением. Например:

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

каков лучший способ смешивания VideoSupport вид (объект события и несколько методов) с UserProfile посмотреть?

6 58

6 ответов:

подчеркивания.библиотека js предоставляет extend метод, который делает то, что вы хотите. Вы можете определить функциональность для любого объекта, а затем буквально скопировать и вставить все методы и атрибуты из этого объекта в другой.

магистрали!--1--> методы на представлениях, моделях и маршрутизаторах являются оболочкой вокруг подчеркивания extend.
 var MyMixin = {
  foo: "bar",
  sayFoo: function(){alert(this.foo);}
}

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

_.extend(MyView.prototype, MyMixin);

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

Я мог бы рекомендовать использовать костяк.Коктейль который обеспечивает действительно лаконичный способ указания миксинов (которые уважают наследование):

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

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

я подробно описал его в этом блоге.

вы можете использовать этот gist https://gist.github.com/3652964

можно использовать костяк.Смешать библиотека который использовал миксины, встроенные в цепь прототипа

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"
    }
});

мне нужна была возможность переопределять и вызывать смешанные методы (ALA super) ближе к тому, как ruby обрабатывает модули. И простой метод расширения будет сбивать метод mixin, если он существует в классе. Так как я строю все это в CoffeeScript у меня есть доступ к супер объект, который позволяет мне прокладку методов. Он также автоматически объединит объект events, чтобы вы могли определить обработчики событий в 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) 

    @

использование

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

другой вариант костяк.Совет который обеспечивает мощность миксинов в стиле AOP (вы можете ввести пользовательское поведение до,после или вокруг вызовы методов расширенного объекта).