2011-04-19 14 views
18

Tengo una colección que contiene algunos de los usuarios. Parte de la información que se necesita es cuántos totales hay, cuántas páginas, etc. ¿Cómo devuelvo esto al cliente? ¿O tienen que venir de una vista separada en cuyo caso necesitaré más de una llamada Ajax? Me gustaría tener la colección fetch() y también recibir algunos de estos "metadatos". ¿Cuál es una buena manera de manejar esto?backbone.js - obteniendo datos adicionales junto con la solicitud

+1

¿Podría dar más información? ¿Cómo se ve tu servidor? ¿Qué navegadores necesitas para apoyar? ¿Con qué frecuencia obtienes tus datos? – tjameson

+0

@tjameson Mi servidor es solo nginx usando php. No necesito admitir ningún navegador en particular (solo puedo apoyar Chrome y Firefox si quiero). Obtengo mis datos con relativa frecuencia (son solo operaciones crud) cambiando el número de página o haciendo una búsqueda rápida, etc. – Matthew

Respuesta

35

En general, es necesario manejar esto de la clase de colección de análisis método. Su responsabilidad es tomar la respuesta y devolver una serie de atributos del modelo. Sin embargo, podría hacer más que eso si lo deseara si no le importase que el método de análisis sintáctico tenga esta responsabilidad adicional.

UserList = Backbone.Collection.extend({ 

    model: User, 

    url: '/users', 

    parse: function(data) { 
     if (!data) { 
      this.registered_users = 0; 
      return []; 
     } 
     this.registered_users = data.registered_users; 
     var users = _(data.users).map(
      function(user_data) { 
       var user = {}; 
       user['name'] = user_data.name; 
       return user; 
      } 
     ); 
     return users; 
    } 
}); 

Así que en el anterior ejemplo trivial, presumir el servidor devuelve una respuesta que contiene un recuento de usuarios registrados y y una serie de atributos de usuario. Ambos analizarían y devolverían los atributos del usuario y elegirían el recuento de usuarios registrados y simplemente lo establecerían como una variable en el modelo.
El método de análisis se llamará como parte de una búsqueda. Así que no hay necesidad de modificar la búsqueda, solo use el método de enlace incorporado que tiene.

Los puristas dirían que le está dando al método de análisis una responsabilidad secundaria que podría sorprender a algunas personas (por ejemplo, devolver algo y modificar el estado del modelo). Sin embargo, creo que esto está bien.

1

Una forma de hacerlo es anular el método Collection::fetch() para que analice estos metadatos de la respuesta. Usted podría tener su backend devuelve una respuesta como esta:

{ 
    "collection": [ 
     { ... model 1 ... }, 
     { ... model 2 ... }, 
     ... 
    ], 
    "total_rows": 98765, 
    "pages":  43 
} 

En el método de fetch que anula el método original Backbone.Collection::fetch(), que puede manejar cada propiedad del objeto por separado. He aquí que podría hacer la anulación con un fetch método ligeramente modificado:

_.extend(Backbone.Collection.prototype, { 
    fetch : function(options) { 
    options || (options = {}); 
    var collection = this; 
    var success = options.success; 
    options.success = function(resp) { 
     // Capture metadata 
     if (resp.total_rows) collection.total_rows = resp.total_rows; 
     if (resp.pages)  collection.pages  = resp.pages; 

     // Capture actual model data 
     collection[options.add ? 'add' : 'refresh'](
     collection.parse(resp.collection), options); 

     // Call success callback if necessary 
     if (success) success(collection, resp); 
    }; 
    options.error = wrapError(options.error, collection, options); 
    (this.sync || Backbone.sync).call(this, 'read', this, options); 
    return this; 
}); 

Tenga en cuenta que este enfoque utilizando _.extend afectará a todos los sus clases que se extienden Backbone.Collection.

De esta manera, no tiene que hacer 2 llamadas por separado al servidor.

+0

No creo que anular un método de framework sea el enfoque correcto para resolver este problema.En su lugar, desea vivir dentro de los métodos de gancho para lograr lo que se le pide. Parse parece ser un lugar apropiado para este tipo de cosas. La anulación de un método de estructura deja el peligro de que cuando desee actualizar backbone.js, es posible que las cosas no funcionen como se esperaba o que no pueda aprovechar cualquier nueva funcionalidad que haya sido asignada a ese método. –

+0

Tiene razón, generalmente no desea afectar todos los métodos que heredan del prototipo de marco. Por alguna razón, asumí que OP deseaba esta funcionalidad en todas las clases de Colección y anular el método de marco es una manera conveniente de hacerlo. El método 'parse' parece ser un mejor lugar para hacer esto, de todos modos. – Sam

0

Arrancaría la información en pagecreation. Escriba la información en el documento html cuando el servidor crea el sitio. Así no tienes que tener una llamada ajax en absoluto. Lo hago con toda la colección en ordner para no cargar primero la página y luego esperar a que la llamada ajax devuelva la información necesaria.

Ejemplo de código con Python:

Línea 64: https://github.com/ichbinadrian/maps/blob/master/python/main.py < - de aquí

Línea 43: https://github.com/ichbinadrian/maps/blob/master/templates/index.html < - entrar aquí

Cuestiones relacionadas