backbone.js cambia el parámetro de URL de un modelo y la búsqueda no actualiza los datos obtenidos
Frecuentes
Visto 36,018 equipos
12
Tengo el siguiente modelo:
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'});
Uso esta variable global 'mod' para obtener algunos datos en este modelo desde el backend.
// fetch
mod.fetch({
success: function(){ ...},
error: ...
});
Todo lo anterior funciona bien... Mi problema: Quiero reutilizar este modelo cambiando el restablecimiento de la URL y la búsqueda de llamadas, pero no actualiza la URL de alguna manera. He probado 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 configuro la URL de mi modelo para poder llamar a fetch() y obtener datos de la URL actualizada? Me estoy perdiendo de algo. Gracias por cualquier sugerencia ..
ACTUALIZACIÓN 1: Básicamente, no puedo obtener valores actualizados si lo hice
model.set({url: 'new value'});
seguido por
model.fetch();
'modelo' es una variable global. Crear una nueva instancia de 'modelo' funciona:
model = new Model({url:'/some/other/url'});
model.fetch();
sin embargo, funciona según sea necesario. ¿Significa esto que una instancia de modelo está permanentemente adjunta a una URL y no se puede restablecer?
RESPUESTA A MI PREGUNTA en la ACTUALIZACIÓN 1 La instancia del modelo no está adjunta de forma permanente 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.
4 Respuestas
2
Puede configurar la URL como opción en la función de búsqueda, así:
var mod = new MyModel();
mod.fetch({
url: '/some/other/url',
data: {}
});
respondido 13 mar '17, 16:03
4
model.urlRoot = "/your/url"
OR
model.urlRoot = function(){ return "/your/url"; }
OR
model.url = "/your/url"
OR
model.url = function(){ return "/your/url"; }
La propiedad 'url' predeterminada 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 tranquilos de Backbone, anule esto para cambiar el punto final al 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, buscará la url de la colección a la que pertenece el modelo. Definir urlRoot en lugar de url tiene la ventaja de recurrir a la url de colección en caso de que urlRoot sea nulo.
Respondido 16 Feb 14, 22:02
gracias por tomarte tu tiempo para responder! Estaba buscando una forma de cambiar la URL en un modelo de forma dinámica en función de la URL que genera mi aplicación. La respuesta que verifiqué funciona muy bien para mí. - Vikram
24
Después de haber entendido la explicación de @tkone...
Si todavía quieres tener una dinámica Model.url
siempre puedes retrasar su construcción para tiempo de ejecución, prueba esto:
window.MyModel = Backbone.Model.extend({
url: function(){
return this.instanceUrl;
},
initialize: function(props){
this.instanceUrl = props.url;
}
}
Respondido 28 Jul 12, 11:07
11
Bueno, la respuesta aquí es que quieres hacer:
mod.url = '/some/other/url'
La URL no es parte de la instancia del modelo en sí, sino un atributo del MyModel
objeto desde el que está creando su instancia de modelo. Por lo tanto, simplemente lo configuraría como si fuera una propiedad de objeto de JavaScript normal. set
se usa solo cuando los datos que está configurando (o por el contrario obteniendo con get
) es en realidad un atributo de los datos que desea enviar/recibir del servidor.
Pero por qué está cambiando la URL es la pregunta que deberíamos hacernos. La idea detrás del modelo/sistema de recopilación de Backbone es que habla con un punto final REST y cada modelo tiene un punto final correspondiente.
Como si tuviera un blog y ese blog tiene un objeto de "entrada" que está disponible en:
/rest/entry/
Y tienes un modelo Backbone para Entry:
Entry = Backbone.Model.extend({urlBase: '/rest/entry'});
Ahora cuando tu save
or fetch
Backbone sabe cómo funciona esto.
Entonces, como si estuvieras haciendo un nuevo modelo:
e = new Entry();
e.set({title: "my blog rulez", body: "this is the best blog evar!!!!1!!"});
e.save();
Esto haría que Backbone hiciera una solicitud HTTP POST para /rest/entry
con el cuerpo:
{
"title": "my blog rulez",
"body": "this is the best blog evar!!!!1!!"
}
(Cuando haces tu mod.set({url: '/some/other/url'});
en realidad estás 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"
}
Luego, el servidor respondería con una respuesta HTTP 200 (o 201) con el mismo modelo, solo con, por ejemplo, un ID adjunto:
{
"id": 1,
"title": "my blog rulez",
"body": "this is the best blog evar!!!!1!!"
}
Y eso no es lo que estás buscando, ¿verdad?)
Ahora tienes este modelo y tiene una identificación. Esto significa que si lo 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ás hablando de ID 1 en el /rest/entry/
punto final, por lo que sabe actualizar un registro existente (y devolver un HTTP 200).
TL; DR
No cambie la URL, Backbone lo hará. Cree un nuevo modelo para una nueva pieza de datos.
Respondido 27 Jul 12, 20:07
gracias por tu explicacion! Tengo un modelo y una url param assoc con eso. cuando inicializo este modelo, paso un valor de url y llamo a fetch(). Ahora quiero cambiar este valor de 'url' ya que los datos obtenidos en este modelo seguirán teniendo los mismos parámetros: por ejemplo url1: /top ; url2: /arriba/filtro1 ; url3: /top/filter2 . No estoy seguro de si es una buena práctica, pero las 3 URL devolverán los mismos datos desde el backend, excepto que se filtrará según lo especificado. Necesito cambiar entre URL en función de las 'pestañas' en las que se hizo clic. Puedo tener varios modelos como mencionaste, pero estaba pensando si podría reutilizarlos. - Vikram
@Vikram, ¿así que está tratando de recuperar solo un conjunto limitado de datos filtrados por su parámetro de filtro? Recomendaría hacer una nueva colección para cada conjunto de datos y cambiar el url
atributo de la colección. Entonces tendrías una colección llamada filter1
cuyo atributo de URL está establecido en /top/filter1
, Etcétera. - toque
si precisamente! devuelve el mismo tipo de datos solo que algunas filas pueden filtrarse según el filtro aplicado... por lo que estaba considerando reutilizar ya que no tengo que realizar un seguimiento (también estoy conservando los modelos localmente) de muchos modelos diferentes que contienen datos similares.... - Vikram
@Vikram Si los datos son todos iguales (ya que todos son del mismo modelo), manejaría esto en el nivel de colección, que es exactamente para lo que están diseñadas las colecciones de backbone. Es un grupo de instancias del mismo modelo en una agrupación que le permite ordenar, iterar, etc. - toque
gracias por sus comentarios... Todavía tengo una pregunta y puede sonar repetitiva, pero ¿cree que este escenario es posible (puede ser una mala práctica, pero sigue preguntando): var model = new Model({url:'/some/ URL'}); model.fetch({success: function(){//hacer algo con los datos}}); model.set(url, '/some/other/url') //NOTA: No estoy haciendo save()....solo set()... model.fetch() obtiene otros datos? ... digamos que las 3 URL que mencioné en el comentario anterior devuelven solo 1 fila (Consulta SQL con Cláusula LIMIT 1) pero una fila diferente según el filtro ... entonces creo que un Modelo sería suficiente en lugar de Colección - Vikram
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas javascript backbone.js or haz tu propia pregunta.
¿Por qué estás cambiando la URL? la idea detrás de un servicio web RESTful es que su objeto siempre esté disponible en la misma URL (con una ID según sea necesario para un objeto específico) - tkone