2012-07-27 15 views
12

tengo el siguiente modelo:Backbone.js cambio de parámetro url de un modelo y traen no actualiza datos captados

window.MyModel = Backbone.Model.extend({ 
    initialize: function(props){ 
      this.url = props.url; 
    } 

    parse: function(){ 

      // @override- parsing data fetched from URL 
    } 


}); 

// instantiate 
    var mod = new MyModel({url: 'some/url/here'}); 

puedo utilizar esta variable global 'mod' a buscar algunos datos en este modelo de back-end.

// fetch 

mod.fetch({ 
     success: function(){ ...}, 
     error: ... 

}); 

Todo lo anterior funciona bien .... mi problema: Quiero volver a utilizar este modelo, cambiando restablecer la URL y llamar a ir a buscar pero no actualiza la url de alguna manera. He intentado lo siguiente:

mod.fetch({ 
     data: {url:'/some/other/url'}, 
     postData: true, 
     success: function(){ //process data}, 
     error: ... 
    }); 


mod.set({url: '/some/other/url'}); 
// called fetch() without data: and postData: attributes as mentioned in previous 

¿Cómo se configura la dirección URL de mi modelo por lo que podría llamar fetch() y recupera los datos de URL actualizada? Me estoy perdiendo de algo. Gracias por cualquier punteros ..

ACTUALIZA 1: Básicamente, no estoy en condiciones de obtener valores actualizados si lo hiciera

model.set({url: 'new value'}); 

seguido por

model.fetch(); 
'modelo'

es una variable global . Creando una nueva instancia de 'modelo' funciona:

model = new Model({url:'/some/other/url'}); 
    model.fetch(); 

Sin embargo, funciona como se requiere. ¿Esto significa que una instancia modelo está permanentemente unida a una url y no se puede restablecer?

respuesta a mi pregunta en ACTUALIZACIÓN 1 instancia modelo no está conectado permanentemente a una URL. Se puede restablecer dinámicamente. Lea la explicación detallada de @ tkone y luego la solución de @fguillens para una mejor comprensión.

+0

por qué están cambiando la URL? la idea detrás de un servicio web REST es que su objeto siempre está disponible en la misma URL (con una ID como sea necesaria para un objeto específico) – tkone

Respuesta

24

Después de haber comprendido la @tkone 's explicación ...

Si todavía quiere tener una dinámica Model.url siempre se puede retrasar su construcción a tiempo de ejecución, intente esto:

window.MyModel = Backbone.Model.extend({ 
    url: function(){ 
    return this.instanceUrl; 
    }, 
    initialize: function(props){ 
    this.instanceUrl = props.url; 
    } 
} 
+4

Puedes hacer: 'mm = new MyModel; mm.url = '/ mynewurl /'; 'también. Backbone es súper flexible con esto. – tkone

+0

@fguillen - ¡Gracias! esto retrasar la construcción para correr el tiempo hizo el truco! – Vikram

+0

@tkone - gracias de nuevo! para todos sus consejos útiles – Vikram

11

Bueno, la respuesta es que usted quiere hacer:

mod.url = '/some/other/url' 

La URL no es parte de la instancia del modelo en sí, sino más bien un atributo del objeto MyModel que está creando su ejemplo de modelo de. Por lo tanto, simplemente lo configuraría como si fuera una propiedad de objeto JavaScript normal. set se usa solo cuando los datos que está configurando (o al contrario que con get) son en realidad un atributo de los datos que desea enviar/recibir del servidor.

Pero la razón por la que está cambiando la URL es la pregunta que debemos hacernos. La idea detrás del sistema de colección/modelo de Backbone es que hablas con un punto final REST y cada modelo tiene un punto final correspondiente.

como que tienes un blog y que blog tiene un objeto "de entrada", que está disponible en:

/rest/entry/ 

y usted tiene un modelo de columna vertebral de la entrada:

Entry = Backbone.Model.extend({urlBase: '/rest/entry'}); 

Ahora cuando save o fetch Backbone sabe cómo funciona esto.

Así como usted está haciendo un nuevo modelo:

e = new Entry(); 
e.set({title: "my blog rulez", body: "this is the best blog evar!!!!1!!"}); 
e.save(); 

Esto entonces haría Backbone hacer una petición HTTP POST a /rest/entry con el cuerpo:

{ 
    "title": "my blog rulez", 
    "body": "this is the best blog evar!!!!1!!" 
} 

(Cuando usted hace su mod.set({url: '/some/other/url'}); en realidad está agregando un campo llamado url al conjunto de datos, por lo que el servidor enviaría "url": "/some/other/url" como parte de ese cuerpo JSON POST anterior:

{ 
    "title": "my blog rulez", 
    "body": "this is the best blog evar!!!!1!!", 
    "url": "/some/other/url" 
} 

El servidor sería entonces responderá con una respuesta HTTP 200 (o 201) con el mismo modelo, sólo con, como, por ejemplo, y la identificación adherida:

{ 
    "id": 1, 
    "title": "my blog rulez", 
    "body": "this is the best blog evar!!!!1!!" 
} 

Y eso no es lo que estás buscando para, ¿verdad?)

Ahora tienes este modelo y tiene una identificación. Esto significa que si cambia:

e.set('title', 'my blog is actually just ok'); 
e.save() 

Backbone ahora realiza una solicitud HTTP PUT en /rest/entry/1 para actualizar el recurso en el servidor.

El servidor ve que está hablando de ID 1 en el punto extremo /rest/entry/, por lo que sabe actualizar un registro existente (y enviar un HTTP 200).

TL; DR

no cambie la dirección URL, Backbone hará. Haga un nuevo modelo para una nueva pieza de datos.

+0

¡gracias por su explicación! Tengo un modelo y url param assoc con eso. cuando inicializo este modelo paso un valor de url y llamo fetch(). Ahora quiero cambiar este valor 'url' ya que los datos obtenidos en este modelo todavía tendrán los mismos params: por ejemplo url1:/top; url2:/top/filter1; url3:/top/filter2. No estoy seguro de si es una buena práctica, pero las 3 URL devolverán los mismos datos desde el servidor, excepto que habrá filtrado según lo especificado. Necesito cambiar entre las URL en función de las 'pestañas' en las que se hace clic. Puedo tener varios Modelos como mencionas, pero estaba pensando si podría reutilizarlos. – Vikram

+0

déjame saber lo que piensas – Vikram

+0

@Vikram por lo que estás tratando de recuperar solo un conjunto limitado de datos filtrados por tu parámetro de filtro? Yo recomendaría hacer una nueva colección para cada conjunto de datos, y cambiar el atributo 'url' de la colección. Por lo tanto, tendrías una colección llamada 'filter1' cuyo atributo URL está establecido en'/top/filter1', y así sucesivamente. – tkone

3
model.urlRoot = "/your/url" 

O

model.urlRoot = function(){ return "/your/url"; } 

O

model.url = "/your/url" 

O

model.url = function(){ return "/your/url"; } 

defecto 'url' propiedad de un objeto Backbone.Model es la siguiente. Backbone.js doc dice:

URL predeterminada para la representación del modelo en el servidor: si está utilizando los métodos de recuperación de Backbone, anule esto para cambiar el punto final que se llamará.

url: function() { 
    var base = getValue(this, 'urlRoot') || getValue(this.collection, 'url') || urlError(); 
    if (this.isNew()) return base; 
    return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.id); 
}, 

Claramente, Primero obtiene el valor de UrlRoot, si no está disponible, que se verá en la dirección URL de la colección a la que pertenece modelo.Al definir urlRoot en lugar de url tiene la ventaja de volver a la url de recopilación en caso de que urlRoot sea nulo.

+0

¡gracias por tomarse su tiempo para responder! Estaba buscando una forma de cambiar la URL en un modelo basado dinámicamente en la URL que genera mi aplicación. La respuesta que revisé funciona muy bien para mí. – Vikram

0

Puede configurar URL como opción en función de captación, así:

var mod = new MyModel(); 
mod.fetch({ 
    url: '/some/other/url', 
    data: {} 
}); 
Cuestiones relacionadas