25

que estoy tratando de hacer un seguimiento del estado en esta aplicación desde Backbone.js:gestión del estado Backbone.js/inicialización vista basado en un fragmento url

enter image description here

que tengo un "ChartAppModel" con una conjunto de valores predeterminados:

ChartAppModel = Backbone.Model.extend({ 

defaults: { 
    countries : [], 
    selectedCountries : [], 
    year : 1970, 
}, 

initialize: function() { 
    loadAbunchOfData(); 
    checkStartState(); 
} 

}); 

Si se les da un fragmento de inicio, este estado por defecto debería sin embargo ser sobrescrito:

var startState = $.deparam.fragment(); //using Ben Alman's BBQ plugin 
this.set({selectedCountries: startState.s, year: startState.y}); 

Ahora, por ejemplo, el SidebarView está listo para ser actualizado:

ChartAppViewSidebar = Backbone.View.extend({ 

initialize: function(){ 
     this.model.bind("change:selectedCountries", this.render); 
}, 

render : function(){ 
     [... render new sidebar with check boxes ...] 
}, 

El problema es que también tengo un controlador de eventos en la barra lateral que actualiza el modelo:

events: { 
"change input[name=country]": "menuChangeHandler", 
}, 

menuChangeHandler : function(){ 
     [... set selectedCountries on model ...] 
}, 

Así que habrá una retroalimentación lazo ... y luego, también me gustaría una manera de empujar a un nuevo estado - por lo que escucho para modelar los cambios:

ChartAppModel = Backbone.Model.extend({ 

initialize: function() { 
    this.bind("change", this.setState); 
} 

}); 

... y relativel Y pronto este estado-manager se derrumbará ...

Preguntas:

1) ¿Cómo init mis puntos de vista (por ejemplo, "el cual casillas de verificación deben ser revisados") basado en el fragmento? (se aprecian sugerencias sobre las mejores prácticas para el estado/estado de inicio que no es una "ruta" típica)

2) ¿Cómo puedo evitar que mis vistas configuren un atributo en el modelo que ellos mismos escuchan?

3) ¿Cómo puedo presionar un nuevo estado basado en una parte del modelo?

Bono :)

4) ¿Cómo establecer el código de la aplicación descrita?

Gracias!

Respuesta

15

Esa es una pregunta bien definida!

Hay una pregunta sobre qué es un modelo. Creo que hay una definición que flota en torno a lo que constituye un modelo en el mundo de la red troncal, y no estoy seguro de que su estrategia esté de acuerdo con esa definición. También está almacenando el estado tanto en la url como en el modelo. Puedes simplemente almacenar el estado en la url, como explicaré.

Si estuviera haciendo esto, habría 2 visitas. Uno para los controles de su aplicación, y anidado dentro de ese para su gráfico: GraphView y AppView. El modelo será la información que va a trazar, no el estado de la interfaz.

Utilice un controlador para iniciar la vista de la aplicación y también para procesar cualquier estado de interfaz definido en la url.

Existe una pregunta acerca de las palancas de estado en Backbone. Las aplicaciones web tradicionales usaban un enlace/url como palanca principal de estado, pero ahora todo eso está cambiando. Aquí es una estrategia posible:

Checkbox Change Event -> Update location fragment -> trigger route in controller -> update the view 
Slider Change Event -> Update location fragment -> trigger route in controller -> update the view 

Lo bueno de esta estrategia es que se encarga del caso en el que se pasan alrededor URLs o bookmarked

Url specified in address bar -> trigger route in controller -> update the view 

voy a echar un vistazo a un recurso ejemplo de pseudo código. Para esto, voy a hacer algunas suposiciones sobre los datos: Los datos son la población de perros en el tiempo (con una granularidad del año), donde el control deslizante debe tener un límite inferior y superior, y los datos de volumen son demasiado grandes para cargarlo todo para el cliente a la vez.

Primero echemos un vistazo al Modelo para representar los datos estadísticos. Para cada punto de la gráfica que necesitamos algo como {población: 27000, año: 2003} Permite representar esto como

DogStatModel extends Backbone.Model -> 

y una colección de estos datos será

DogStatCollection extends Backbone.Collection -> 
    model: DogStatModel 
    query: null // query sent to server to limit results 
    url: function() { 
     return "/dogStats?"+this.query 
    } 

Ahora veamos el controlador. En esta estrategia que propongo, el controlador hace honor a su nombre.

AppController extends Backbone.Controller -> 
    dogStatCollection: null, 
    appView: null, 

    routes: { 
     "/:query" : "showChart" 
    }, 

    chart: function(query){ 
     // 2dani, you described a nice way in your question 
     // but will be more complicated if selections are not mutually exclusive 
     // countries you could have as countries=sweden;france&fullscreen=true 
     queryMap = parse(query) // 
     if (!this.dogStatCollection) dogStatCollection = new DogStatCollection 
     dogStatCollection.query = queryMap.serverQuery 
     if (!this.appView) { 
      appView = new AppView() 
      appView.collection = dogStatCollection 
     } 
     appView.fullScreen = queryMap.fullScreen 
     dogStatCollection.fetch(success:function(){ 
      appView.render() 
     })    
    } 
+0

Y eso fue una gran respuesta: comencé a reconsiderar el uso de "rutas". Pero digamos que tengo un estado de inicio (url) con 5 parámetros: año = 1979, apilado = verdadero, diseño = pantalla completa, seleccionado = [Suecia, Finlandia], zoom = 2. En función de estos parámetros, los datos deberían cargarse, el eje x/y debería calcularse y las vistas deberían mostrarse, etc. ¿Cuál sería el enfoque utilizando rutas? Pseudocódigo es MUY BIENVENIDO: =) – dani

+0

gracias @dani, no estaba seguro de cuán clara era mi explicación. En una relación ligeramente relacionada, tener el control deslizante debajo del plano horizontal podría añadir un poco de confusión para el usuario. Actualizaré la respuesta original con algún pseudo código. – 34m0

2

2) ¿Cómo puedo evitar que mis vistas configuren un atributo en el modelo que ellos mismos escuchan?

Usted no lo hace. Su modelo debería estar validando cualquier atributo que intente actualizar para que su vista necesite para escuchar en caso de que falle la configuración del atributo o la validación cambie el valor.

Lo que hace su vista es intenta para establecer un valor en el modelo, el modelo luego lo establece, cambia los datos y lo establece, o lo rechaza. Su vista debe actualizarse en consecuencia.

3) ¿Cómo puedo presionar un nuevo estado basado en una parte del modelo?

// for each attribute 
_.each(["attribute1", "attribute2", "attribute3", ...], _.bind(function(val) { 
    // bind the change 
    // bind the setState with `this` and the `value` as the first parameter 
    this.bind("change:" + value, _.bind(this.setState, this, value)); 
}, this)); 
+0

2) tiene sentido - lo que no es establecer el atributo modelo desde el punto de vista problema y luego escuchar a cambiar en el mismo atributo? 3) ¿Entonces, básicamente, me sumo a cada atributo del modelo al que me gustaría invocar el método setState? Gracias! p. ¿Alguna entrada en el manejo del estado de inicio/inicio? – dani

+0

@dani los otros dos no tengo entrada porque solo he hecho juguetes con columna vertebral;) y no uso jQuery BBQ – Raynos

+0

Thx de todos modos por su ayuda: =) (y esos _.binds no son juguetes!) – dani

Cuestiones relacionadas