Los valores predeterminados de Backbone.js a la vista?

Estoy trabajando en Backbone.js y me preguntaba si se puede configurar los valores predeterminados de la misma manera que usted puede establecer los valores predeterminados de un modelo?

10 Kommentare

  1. 31

    Lo que usted puede hacer es establecer los valores predeterminados en la initialize función.

    defaults: {
      display: 'list'
    },
    
    initialize: function() {
      this.options = _.extend({}, this.defaults, this.options);
    }

    Esto funcionará para opciones normal, pero no anular las opciones especiales (los que columna vertebral almacena en el objeto de la vista, como bien ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName'])

    Ver una demo del: http://jsfiddle.net/dira/7MmQE/1/

    • Limpiador de aplicación. Me gusta. +1
    • Esto no funciona correctamente. demo2 las opciones de sobrescritura demo opciones: jsfiddle.net/cwarden/q2pxw
    • La gente fina en #documentcloud señaló el problema. este.los valores predeterminados se viene desde el prototipo, es el mismo objeto en ambos casos. La ampliación de un nuevo objeto con esto.los valores predeterminados y este.opciones soluciona el problema. He editado el @dira la respuesta adecuada.
    • El uso de _.los valores predeterminados() es una solución aún mejor.
    • Tuve el mismo problemas, pero después de navegar durante algún tiempo. He encontrado este como (github.com/documentcloud/underscore/issues/106) esto.opciones = _.extend({}, este.valores predeterminados de esta.las opciones)
    • Y cuando estás heredando desde este punto de vista y desea proporcionar a los distintos valores predeterminados? this.defaults2? Hrm…
    • este.las opciones ya no rellenan de forma automática como de la columna vertebral 1.1.0. La solución más sencilla a este problema es el uso de la columna vertebral.viewOptions plugin.

  2. 26

    Para columna vertebral 1.1 o superior

    Enfoque a: OptionsInLiteral con _.los valores predeterminados en inicializar

    var MyView = Backbone.View.extend({
      options: {
        enabled: true,
        align:   "left"
      },
      initialize: function (options) {
        #be sure to do the '|| {}' here so 'new MyView()' works
        this.options = _.defaults(options || {}, this.options);
      }
    });

    Enfoque B: el Uso de la viewOptions plugin (o similar)

    https://github.com/rotundasoftware/backbone.viewOptions

    Gracias a @BraveDave para señalar esto en un comentario.

    Para columna vertebral antes de la versión 1.1 (referencia histórica, FYI).

    Aquí está la columna vertebral problema donde parece que el núcleo del equipo es más probable que deshacerse de this.options y la lógica en _configure por completo.

    Utilizar una de las opciones de propiedad y siempre uso este.opciones de

    Hay mucha confusión sobre esta cuestión e incluso un muy upvoted y aceptado respuesta incorrecta. Espero que esta respuesta demuestra una verdadera solución correcta así como señalar los errores en todos los otros candidatos respuestas.

    Para trabajar en armonía con el Backbone.View de los padres de la clase, se supone que para incluir un options propiedad del objeto literal de pasar a Backbone.View.extend.

    var OptionsInLiteral = Backbone.View.extend({
      options: {flavor: "vanilla"},
      initialize: function (options) {
        console.log("OptionsInLiteral.initialize first argument", options);
        console.log("OptionsInLiteral.initialize this.options", this.options);
      }
    });

    Aquí están algunos ejemplos y lo que registro a la consola.

    new OptionsInLiteral();
        //OptionsInLiteral.initialize first argument undefined
        //OptionsInLiteral.initialize this.options Object {flavor: "vanilla"}
    new OptionsInLiteral({flavor: "chocolate"});
        //OptionsInLiteral.initialize first argument Object {flavor: "chocolate"}
        //OptionsInLiteral.initialize this.options Object {flavor: "chocolate"}
    new OptionsInLiteral({flavor: "strawberry", sprinkles: true});
        //OptionsInLiteral.initialize first argument Object {flavor: "strawberry", sprinkles: true}
        //OptionsInLiteral.initialize this.options Object {flavor: "strawberry", sprinkles: true}

    Este correctamente tomar ventaja de Backbone.View._configure, que como de la columna vertebral 1.0.0 se parece a esto:

    _configure: function(options) {
      if (this.options) options = _.extend({}, _.result(this, 'options'), options);
      _.extend(this, _.pick(options, viewOptions));
      this.options = options;
    },

    Lo que esto significa es:

    • Si su punto de vista literal de objeto contiene options, _configure bien de tratar a las personas como valores por defecto, los reemplace con propiedades que se pasa en el constructor, y establecer el resultado final del objeto como this.options. Hurra. Eso es lo que queremos.
    • Esto funcionará incluso si el punto de vista del constructor se invoca sin argumentos. Hurra. También lo queremos.
    • Porque _.result se utiliza aquí, el options propiedad puede ser una Object o un function, y si es una función, se llama y el valor de retorno será utilizado.

    Este también es aceptable y permite a los predeterminados a ser único para cada instancia.

    var OptionsFunctionInLiteral = Backbone.View.extend({
      options: function () {
        return {
          flavor: "vanilla",
          created: Date(),
          collection: new Backbone.Collection()
        };
      },
      initialize: function (options) {
        console.log("OptionsFunctionInLiteral.initialize first argument", options);
        console.log("OptionsFunctionInLiteral.initialize this.options", this.options);
      }
    });

    Aquí están algunos ejemplos y lo que registro a la consola.

    new OptionsFunctionInLiteral();
        //OptionsFunctionInLiteral.initialize first argument undefined
        //OptionsFunctionInLiteral.initialize this.options Object {flavor: "vanilla", created: "Wed Jun 19 2013 16:20:16 GMT-0600 (MDT)", collection: Backbone.Collection}
    new OptionsFunctionInLiteral({flavor: "chocolate"});
        //OptionsFunctionInLiteral.initialize first argument Object {flavor: "chocolate"}
        //OptionsFunctionInLiteral.initialize this.options Object {flavor: "chocolate", created: "Wed Jun 19 2013 16:21:17 GMT-0600 (MDT)", collection: Backbone.Collection}
    new OptionsFunctionInLiteral({flavor: "strawberry", sprinkles: true});
        //OptionsFunctionInLiteral.initialize first argument Object {flavor: "strawberry", sprinkles: true}
        //OptionsFunctionInLiteral.initialize this.options Object {flavor: "strawberry", created: "Wed Jun 19 2013 16:22:26 GMT-0600 (MDT)", collection: Backbone.Collection, sprinkles: true}

    Por qué usted debe utilizar siempre este.opciones

    Por lo que el de arriba es genial con la salvedad de que si su punto de vista del constructor es llamado sin argumentos, dentro de su initialize función this.options va a existir y ser correcta, pero la llanura options argumento de la initialize función será undefined.

    initialize: function (options) {
      console.log(options.flavor); //BUG! options is undefined. Uncaught exeption. :-(
      console.log(this.options); //correct
    }

    Así, cuando defino mi inicializar, incluso no me especificar el options argumento a la función como un recordatorio de que no lo uso. En general, se desea omitir la options argumento para initialize porque no contiene los valores predeterminados de todos modos.

    Buggy respuesta: _.extender(este.valores predeterminados de esta.opciones)

    Esta respuesta tiene un bug en el que involuntariamente modifica los valores predeterminados para todas las futuras instancias cada vez que una instancia es instatiated.

    var DefaultsExtendView = Backbone.View.extend({
      defaults: {flavor: "vanilla"},
      initialize: function (options) {
        console.log("initialize 1st argument", options);
        this.options = _.extend(this.defaults, this.options);
        console.log("initialize this.options", this.options);
      }
    });
    
    new DefaultsExtendView(); //OK
    new DefaultsExtendView({flavor: "chocolate"}); //OK
    new DefaultsExtendView(); //BUG! You get chocolate instead of vanilla

    Buggy respuesta: si (opciones.foo)

    var myView = Backbone.View.extend({
        foo: "default_value",
    
        initialize: function(options) {
            if(options.foo) {
                foo = options.foo;
            }
        }
    });
    
    new myView(); //BUG! options is undefined, uncaught exception
    //TypeError: Cannot read property 'foo' of undefined

    Cuidado de las opciones objeto de la instancia y valores predeterminados específicos del

    Una de las respuestas a esta pregunta sugiere lo siguiente:

    var DefaultsView = Backbone.View.extend({
      defaults: {
        collection: new Backbone.Collection()
      },
      initialize: function () {
        _.defaults(this.options, this.defaults);

    Que es casi seguro que no lo desea y un error. Si usted hace 10 puntos de vista, todos ellos estarán compartiendo la misma instancia de Backbone.Collection como no va a ser sólo 1 instancia creada cuando la vista subclase está definida. Esto es seguro para confundir al agregar un modelo para view9 de la colección y se muestra en todas las vistas. Lo más probable es que quiera es otra nueva instancia de la colección para cada vista de la instancia, y para conseguir lo que se necesita para hacer options ser una función como en mi ejemplo anterior.

    Resumen de la forma correcta de hacer esto

    1. uso options: {...} o options: function () {...}
    2. Declarar su initialize sin argumentos
    3. Acceder a tu adecuadamente fallidos opciones como this.options

    Ejemplo Repetitivo

    var MyView = Backbone.View.extend({
      options: {flavor: "vanilla"},
      initialize: function () { //note no declared arguments
          //use this.options here as needed and all is well
      }
    });

    De trabajo jsfiddle

    http://jsfiddle.net/DUc25/

    • this.options fue, de hecho, cayó en la columna vertebral 1.1.0 y este enfoque no funcionará más. Sólo el uso de la columna vertebral.viewOptions plugin.
    • Gracias, @BraveDave. He actualizado la respuesta. Déjeme saber si usted ve cualquier problema en el fragmento de código en la parte superior.
  3. 13

    Para columna vertebral 1.1 o superior

    Enfoque a: OptionsInLiteral con _.los valores predeterminados en inicializar

    var MyView = Backbone.View.extend({
      options: {
        enabled: true,
        align:   "left"
      },
      initialize: function (options) {
        #be sure to do the '|| {}' here so 'new MyView()' works
        this.options = _.defaults(options || {}, this.options);
      }
    });

    Enfoque B: el Uso de la viewOptions plugin (o similar)

    columna vertebral.viewOptions

    Gracias a @BraveDave para señalar esto en un comentario.

    Para columna vertebral antes de la versión 1.1 (referencia histórica, FYI).

    Aquí está la columna vertebral problema donde parece que el núcleo del equipo es más probable que deshacerse de this.options y la lógica en _configure por completo.

    Utilizar una de las opciones de propiedad y siempre uso este.opciones de

    Hay mucha confusión sobre esta cuestión e incluso un muy upvoted y aceptado respuesta incorrecta. Espero que esta respuesta demuestra una verdadera solución correcta así como señalar los errores en todos los otros candidatos respuestas.

    Para trabajar en armonía con el Backbone.View de los padres de la clase, se supone que para incluir un options propiedad del objeto literal de pasar a Backbone.View.extend.

    var OptionsInLiteral = Backbone.View.extend({
      options: {flavor: "vanilla"},
      initialize: function (options) {
        console.log("OptionsInLiteral.initialize first argument", options);
        console.log("OptionsInLiteral.initialize this.options", this.options);
      }
    });

    Aquí están algunos ejemplos y lo que registro a la consola.

    new OptionsInLiteral();
        //OptionsInLiteral.initialize first argument undefined
        //OptionsInLiteral.initialize this.options Object {flavor: "vanilla"}
    new OptionsInLiteral({flavor: "chocolate"});
        //OptionsInLiteral.initialize first argument Object {flavor: "chocolate"}
        //OptionsInLiteral.initialize this.options Object {flavor: "chocolate"}
    new OptionsInLiteral({flavor: "strawberry", sprinkles: true});
        //OptionsInLiteral.initialize first argument Object {flavor: "strawberry", sprinkles: true}
        //OptionsInLiteral.initialize this.options Object {flavor: "strawberry", sprinkles: true}

    Este correctamente tomar ventaja de Backbone.View._configure, que como de la columna vertebral 1.0.0 se parece a esto:

    _configure: function(options) {
      if (this.options) options = _.extend({}, _.result(this, 'options'), options);
      _.extend(this, _.pick(options, viewOptions));
      this.options = options;
    },

    Lo que esto significa es:

    • Si su punto de vista literal de objeto contiene options, _configure bien de tratar a las personas como valores por defecto, los reemplace con propiedades que se pasa en el constructor, y establecer el resultado final del objeto como this.options. Hurra. Eso es lo que queremos.
    • Esto funcionará incluso si el punto de vista del constructor se invoca sin argumentos. Hurra. También lo queremos.
    • Porque _.result se utiliza aquí, el options propiedad puede ser una Object o un function, y si es una función, se llama y el valor de retorno será utilizado.

    Este también es aceptable y permite a los predeterminados a ser único para cada instancia.

    var OptionsFunctionInLiteral = Backbone.View.extend({
      options: function () {
        return {
          flavor: "vanilla",
          created: Date(),
          collection: new Backbone.Collection()
        };
      },
      initialize: function (options) {
        console.log("OptionsFunctionInLiteral.initialize first argument", options);
        console.log("OptionsFunctionInLiteral.initialize this.options", this.options);
      }
    });

    Aquí están algunos ejemplos y lo que registro a la consola.

    new OptionsFunctionInLiteral();
        //OptionsFunctionInLiteral.initialize first argument undefined
        //OptionsFunctionInLiteral.initialize this.options Object {flavor: "vanilla", created: "Wed Jun 19 2013 16:20:16 GMT-0600 (MDT)", collection: Backbone.Collection}
    new OptionsFunctionInLiteral({flavor: "chocolate"});
        //OptionsFunctionInLiteral.initialize first argument Object {flavor: "chocolate"}
        //OptionsFunctionInLiteral.initialize this.options Object {flavor: "chocolate", created: "Wed Jun 19 2013 16:21:17 GMT-0600 (MDT)", collection: Backbone.Collection}
    new OptionsFunctionInLiteral({flavor: "strawberry", sprinkles: true});
        //OptionsFunctionInLiteral.initialize first argument Object {flavor: "strawberry", sprinkles: true}
        //OptionsFunctionInLiteral.initialize this.options Object {flavor: "strawberry", created: "Wed Jun 19 2013 16:22:26 GMT-0600 (MDT)", collection: Backbone.Collection, sprinkles: true}

    Por qué usted debe utilizar siempre este.opciones

    Por lo que el de arriba es genial con la salvedad de que si su punto de vista del constructor es llamado sin argumentos, dentro de su initialize función this.options va a existir y ser correcta, pero la llanura options argumento de la initialize función será undefined.

    initialize: function (options) {
      console.log(options.flavor); //BUG! options is undefined. Uncaught exeption. :-(
      console.log(this.options); //correct
    }

    Así, cuando defino mi inicializar, incluso no me especificar el options argumento a la función como un recordatorio de que no lo uso. En general, se desea omitir la options argumento para initialize porque no contiene los valores predeterminados de todos modos.

    Buggy respuesta: _.extender(este.valores predeterminados de esta.opciones)

    Esta respuesta tiene un bug en el que involuntariamente modifica los valores predeterminados para todas las futuras instancias cada vez que una instancia es instatiated.

    var DefaultsExtendView = Backbone.View.extend({
      defaults: {flavor: "vanilla"},
      initialize: function (options) {
        console.log("initialize 1st argument", options);
        this.options = _.extend(this.defaults, this.options);
        console.log("initialize this.options", this.options);
      }
    });
    
    new DefaultsExtendView(); //OK
    new DefaultsExtendView({flavor: "chocolate"}); //OK
    new DefaultsExtendView(); //BUG! You get chocolate instead of vanilla

    Buggy respuesta: si (opciones.foo)

    var myView = Backbone.View.extend({
        foo: "default_value",
    
        initialize: function(options) {
            if(options.foo) {
                foo = options.foo;
            }
        }
    });
    
    new myView(); //BUG! options is undefined, uncaught exception
    //TypeError: Cannot read property 'foo' of undefined

    Cuidado de las opciones objeto de la instancia y valores predeterminados específicos del

    Una de las respuestas a esta pregunta sugiere lo siguiente:

    var DefaultsView = Backbone.View.extend({
      defaults: {
        collection: new Backbone.Collection()
      },
      initialize: function () {
        _.defaults(this.options, this.defaults);

    Que es casi seguro que no lo desea y un error. Si usted hace 10 puntos de vista, todos ellos estarán compartiendo la misma instancia de Backbone.Collection como no va a ser sólo 1 instancia creada cuando la vista subclase está definida. Esto es seguro para confundir al agregar un modelo para view9 de la colección y se muestra en todas las vistas. Lo más probable es que quiera es otra nueva instancia de la colección para cada vista de la instancia, y para conseguir lo que se necesita para hacer options ser una función como en mi ejemplo anterior.

    Resumen de la forma correcta de hacer esto

    1. uso options: {...} o options: function () {...}
    2. Declarar su initialize sin argumentos
    3. Acceder a tu adecuadamente fallidos opciones como this.options

    Ejemplo Repetitivo

    var MyView = Backbone.View.extend({
      options: {flavor: "vanilla"},
      initialize: function () { //note no declared arguments
          //use this.options here as needed and all is well
      }
    });

    De trabajo jsfiddle

    http://jsfiddle.net/DUc25/

  4. 2
    var DefaultsView = Backbone.View.extend({
      defaults: {
        collection: new Backbone.Collection()
      },
      initialize: function () {
        _.defaults(this.options, this.defaults);
        //Ensures keys with special meaning (model, collection, id, className, etc.), are attached directly to the view
        Backbone.View.prototype._configure.apply(this, arguments);
      },
      render: function () {
        console.log(this.collection);
      }
    });
    
    var view = new DefaultsView();
    
    view.render();
  5. 2

    Un intento de pato de perforación.
    De la columna vertebral del código fuente:

    var View = Backbone.View = function(options) {
        this.cid = _.uniqueId('view');
        this._configure(options || {});
        this._ensureElement();
        this.initialize.apply(this, arguments);
        this.delegateEvents();
    };

    Vamos a reemplazar _configure:

    //Save _configure method
    var _oldConfigure = Backbone.View.prototype._configure;
    
    Backbone.View.prototype._configure = function(options){
        _.defaults(options, this.defaults); 
        _oldConfigure.call(this, options);
    };

    Ahora La Columna Vertebral.La vista se comporta de la misma como columna vertebral.modelo con respecto a los valores predeterminados, y usted incluso no necesita hacer nada en el constructor/método initialize.

  6. 1

    Por La Columna Vertebral.Vista de la explicación, dice

    constructor /initializenew View([opciones])

    A la hora de crear un nuevo punto de Vista, las opciones que pasan conectados a la
    ver como este.opciones de, para referencia en el futuro. Hay varios especiales
    opciones que, si es aprobada, será conectado directamente a la vista: modelo,
    colección, el, id , className, tagName y atributos. Si la vista
    define una función de inicialización, que será llamado cuando la vista está
    creado por primera vez. Si desea crear una vista que hace referencia a un
    elemento ya en el DOM, pasar en el elemento como una opción: nuevo
    Ver({el: existingElement}).

    Me wounder por qué los valores por defecto no se utiliza en la vista de la misma manera que se utilizan en el Modelo y a la Recolección.

    • Por favor, añade un enlace a la cita
  7. 0

    La solución correcta es similar a la dira el. Simplemente especificando un objeto de opciones en la vista de especificaciones contendrá los valores predeterminados para las opciones de objeto: http://jsfiddle.net/h3cAU/1/

    var ViewDefaultsDemo = Backbone.View.extend({
      options: {
         display: 'list'
      },
    
      render: function() {
        console.log(this.options.display)
      }
    });

    Ver la fuente para Ver._configure para información adicional: https://github.com/documentcloud/backbone/blob/0.9.10/backbone.js#L1332-L1334

  8. 0

    Esta pila es un poco engañoso para mí. Peter Lyons respuesta se parece a la actual correcto a pesar de no tener la mayoría de votos.

    De la columna vertebral docs…

    A la hora de crear un nuevo punto de Vista, las opciones que paso después de que se mezclan en ninguna de las opciones por defecto ya presente en la vista — se unen a la vista como esta.opciones para referencia en el futuro.

    http://backbonejs.org/#View-constructor

    Yo era capaz de hacer que el trabajo mediante la aplicación de una de las opciones en la definición de la clase.

    MyScope.MyView = Backbone.View.extend({
        options: {
            default_prop: 'value1',
            another_default: 'value2'
        }
    }
  9. 0

    Si entiendo la pregunta correctamente, puede configurar los valores predeterminados de esta manera:

    scope.MyView = Backbone.View.extend({
        x: 'x',
    })
    
    var obj = new scope.MyView({
        y: 'y',
    });
    
    console.log( this.options );
    //output: { x: 'x', y:'y' }

    El problema, y el comportamiento no refleja plenamente lo establecido en el constructor de Vista de la documentación, es que los objetos compuestos no son totalmente copiado. Esto es debido a que _configure utiliza underscore.js _.extend y no es recursiva.

    Que significa que si haces algo como esto:

    scope.MyView = Backbone.View.extend({
        x: {
            a: 'a',
        }
    })
    
    var obj = new scope.MyView({
        x: {
            b: 'b',
        }
    });
    
    console.log( this.options );
    //output: { x: { b:'b' } }

    no funciona como se esperaba. Esto es probable que suceda si se pasan los atributos a la vista una tiene atributos por defecto. Los atributos que pasa será sobrescrito.

  10. 0

    Uso de la columna vertebral.viewOptions plugin, que hace exactamente lo que usted está buscando:

    //Add the view options plugin functionality to all our views.
    Backbone.ViewOptions.add( Backbone.View.prototype );
    
    MyView = Backbone.View.extend( {
        options : [
            "type", //normal options are declared like so
            { "label" : "OK" } //options with defaults are declared like so
         ],
    
        initialize : function( options ) {
            this.setOptions( options ); //attaches declared options to the view
    
            console.log( this.label ); //outputs "OK"
            console.log( this.type ); //outputs "button"
        }
    } );
    
    new MyView( { type : "button" } );

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea