2012-02-23 17 views
6

Estoy tratando de escribir una vista Backbone para un navegador de objetos que está diseñado para implementarse en varios lugares con diferentes tipos de objetos y operaciones ligeramente diferentes. ¿Cómo puedo lograr una buena reutilización del código?Backbone View Herencia

He intentado simplemente ampliar la vista de red troncal en mi navegador y luego extender el navegador en mi implementación; sin embargo, esto me deja con algunas propiedades que se comparten. Este es un efecto no deseado ya que los datos se anexan a todas las implementaciones con cada creación de navegador.

¿Podría alguien arrojar luz sobre una manera de resolver este problema o tal vez una solución alternativa?

Éstos son algunos ejemplos de código para darle una mejor idea de cómo su estado actual:

var BrowserView = Backbone.View; 

    _.extend(BrowserView.prototype, Backbone.View.prototype, { 
     className: 'browser', 

     collections: [], 

     events: { 

     }, 

     _events:{ 

     }, 

      initialize: function() { 
      this._initialize(); 
     }, 

     render: function() { 
      this._render(); 
     }, 

     _initialize: function() { 
      this.container = $(this.make('div', {class: 'container'})); 

      this.$el.append(this.container); 

      if (this.options.collections) { 
       this.collections = []; 

       _.each(this.options.collections, this.add, this); 
      } 

      _.extend(this.events, this._events); 

      this.delegateEvents(); 
     }, 

     _render: function() { 
      this.container.empty(); 

      _.each(this.collections, function (view) { 
       this.container.append(view.el); 

       view.render(); 
      }, this); 
     } 
    }); 

    BrowserView.extend = Backbone.View.extend; 

    var ContactBrowserView = BrowserView.extend({ 

    }); 

Como siempre, más de retroalimentación de bienvenida en lo que respecta a cualquier aspecto del fragmento de código que he proporcionado.

Gracias, Alex

EDITAR Mi problema es que las subclases comparten la propiedad de colecciones. Aquí hay un ejemplo de mi propia solución que inicializa la propiedad de colecciones a través de un método heredado. jsfiddle.net/JhZXh/3

Respuesta

4

Es difícil ver cuál es exactamente tu objetivo.

pero esta es la forma en que lo veo si tiene una vista de objeto

var myView = Backbone.View.extend({ 
    foo: "bar" 
}); 

y usted tiene que extender la backbone.View ... entonces que en realidad tienen un nuevo objeto de vista con todo lo de la columna vertebral. vista, y las opciones adicionales que das como parámetros.

si luego vas y crear un segundo punto de vista, que se extiende a su primera obtendrá todo, desde su primer punto de vista, + su propio extras

var mySecondView = myView.extend({ 
    foobar: "[email protected]" 
}); 

si desea crear una instancia de la segunda vista log es foo propiedad todavía llevará a cabo "bar" como valor

var mySecondViewInstance = new mySecondView(); 
console.log("mySecondViewInstance.foo: ", mySecondViewInstance.foo); 
console.log("mySecondViewInstance.foobar: ", mySecondViewInstance.foobar); 

Si creo una nueva instancia de mi primera vista, y cambiar en foo"changed-foo" el registro de foo en mySecondViewInstance seguirá siendo "bar"

var myViewInstance = new myView(); 
myViewInstance.foo = "changed-foo"; 
console.log("mySecondViewInstance.foo: ", mySecondViewInstance.foo); 
console.log("mySecondViewInstance.foobar: ", mySecondViewInstance.foobar); 

un JS-violín jugar un rato con él se puede encontrar aquí: http://jsfiddle.net/saelfaer/uNBSW/

+0

Hola Sander, lo siento mi pregunta no era lo suficientemente descriptivo. También creé un JS-Fiddle para demostrar mejor el núcleo de mi problema. Tal vez debería haber hecho esto desde el principio. Mi problema es que las subclases comparten la propiedad de colecciones. http://jsfiddle.net/JhZXh/3/ –

+0

en cualquier caso, simplemente agregue ese jsfiddle y la descripción a su publicación original, no todos lo encontrarán aquí en el comentario. Lo echaré un vistazo y veré si puedo encontrar una respuesta más adecuada. – Sander

3

Heredar del Backbone.View no funciona, o es bastante complejo .

Debe crear un objeto común, que todos los de la vista heredarán partir, es decir:

var ViewInterface = { 
    events  : { /* ... */ }, 
    initialize : function (options) { /* ... */ }, 
    otherFunction : function (options) { /* ... */ }, 
} 

cada uno de su punto de vista se extendería desde este objeto:

var BrowserView = Backbone.View.extend(_.extend(ViewInterface, { 
    anotherFunction : function (options) { /* ... */ }, 
}) 

var AnotherView = Backbone.View.extend(_.extend(ViewInterface, { 
    yetAnotherFunction : function (options) { /* ... */ }, 
}) 
+0

que funcionaría, pero hasta donde yo sé no es lo que el OP necesita, su problema fue que, en lugar de 'otherFunction', definió una propiedad, que era una colección. y extendiendo desde ese punto de vista, ambos puntos de vista estaban compartiendo la referencia a la colección que presentaba tener su propia colección. es por eso que ahora se sugirió a sí mismo, inicializarlo desde el método de inicialización en lugar de definirlo en la vista en sí. – Sander

+2

esto realmente no funciona, ya que extender se copiará a ViewInterface, y por lo tanto anotherFunction también existirá en AnotherView. – pedroteixeira

11

creo yo' he descubierto la respuesta a mi propio problema.

Creo que la forma correcta de lograr lo que estoy buscando es mover la inicialización de propiedades en el método de inicialización proporcionado por las vistas de Backbone. De esta manera se inicializan

var BrowserView = Backbone.View.extend({ 
    initialize: function() { 
     this.collections = []; 
    } 
}); 

var FileBrowserView = BrowserView.extend({ 
    initialize: function() { 
     BrowserView.prototype.initialize.apply(this); 

     this.collections.push({name: 'Example Collection' + Math.rand()}); 
    } 
}); 


var FileBrowserInstance1 = new FileBrowserView; 
console.log(FileBrowserInstance1.collections); 

var FileBrowserInstance2 = new FileBrowserView; 
console.log(FileBrowserInstance2.collections); 

Vaya aquí para un violín http://jsfiddle.net/yssAT/2/