tutorial source significado redes react example backbone annotated backbone.js

backbone.js - source - ¿La forma más limpia de destruir todos los modelos de una colección en Backbone?



backbone significado (6)

En el primer intento escribí

this.collection.each(function(element){ element.destroy(); });

Esto no funciona, porque es similar a ConcurrentModificationException en Java, donde se eliminan todos los demás elementos.

Intenté vincular el evento "eliminar" en el modelo para destruirse a sí mismo como se sugiere ¿ Destruir un modelo de red troncal en una colección en un solo paso? , pero esto activará 2 solicitudes de eliminación si llamo a destroy en un modelo que pertenece a una colección.

Miré el documento de subrayado y no puedo ver una variante de each() que se desplaza hacia atrás, lo que resolvería la eliminación de cada problema de elementos.

¿Qué sugerirías como la forma más limpia de destruir una colección de modelos?

Gracias


Esto funciona, algo sorprendido de que no pueda usar el guión bajo para esto.

for (var i = this.collection.length - 1; i >= 0; i--) this.collection.at(i).destroy();


Estoy un poco tarde aquí, pero creo que esta es una solución bastante breve, también:

_.invoke(this.collection.toArray(), ''destroy'');


Piggybacking en la respuesta de Sean Anderson. Hay un acceso directo a la matriz de la colección troncal, por lo que podría hacerlo de esta manera.

_.invoke(this.collection.models, ''destroy'');

O simplemente llame a reset() en la colección sin parámetros, destroy método en los modelos en esa colección se activará dos veces.

this.collection.reset();

http://backbonejs.org/#Collection-models


Prefiero este método, especialmente si necesita llamar a destroy en cada modelo, borrar la colección y no llamar DELETE al servidor. Eliminar idAttribute es lo que lo permite.

var myCollection = new Backbone.Collection(); var models = myCollection.remove(myCollection.models); _.each(models, function(model) { model.set(''id'', null); // hack to ensure no DELETE is sent to server model.destroy(); });

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="http://underscorejs.org/underscore-min.js"></script> <script src="http://backbonejs.org/backbone-min.js"></script>


Recientemente me encontré con este problema también. Parece que lo resolvió, pero creo que una explicación más detallada también podría ser útil para otros que se preguntan exactamente por qué ocurre esto.

Entonces, ¿qué está pasando realmente?

Supongamos que tenemos una colección (biblioteca) de modelos (libros).

Por ejemplo:

console.log(library.models); // [object, object, object, object]

Ahora, veamos y borre todos los libros usando su enfoque inicial:

library.each(function(model) { model.destroy(); });

each es un método de subrayado que se mezcla con la colección Backbone . Utiliza la referencia de colecciones a sus modelos ( library.models ) como argumento predeterminado para estos diversos métodos de colección de guión bajo. Bien, seguro. Eso suena razonable.

Ahora, cuando el modelo llama a destroy , también activa un evento "destroy" en la colección , que luego eliminará su referencia al modelo . Dentro de remove , te darás cuenta de esto:

this.models.splice(index, 1);

Si no está familiarizado con el splice , consulte el doc . Si es así, puede ver por qué esto es problemático.

Sólo para demostrar:

var list = [1,2]; list.splice(0,1); // list is now [2]

¡Esto hará que each bucle salte elementos porque la referencia a los objetos del modelo a través de los models se está modificando dinámicamente!

Ahora, si estás usando JavaScript <1.6, entonces puedes encontrarte con este error:

Uncaught TypeError: Cannot call method ''destroy'' of undefined

Esto se debe a que en la implementación de subrayado de each , se forEach a su propia implementación si falta el forEach nativo. Se queja si elimina un elemento a mitad de la iteración porque todavía intenta acceder a elementos no existentes.

Si forEach el forEach nativo, entonces se usaría en su lugar y no obtendrías ningún error.

¿Por qué? Según el doc .

Si los elementos existentes de la matriz se modifican, o se eliminan, su valor pasado a callback será el valor en el momento en que cada uno los visite; Los elementos que se eliminan no se visitan .

Entonces, ¿cuál es la solución?

No uses collection.each si estás eliminando modelos de la colección. Use un método que le permita trabajar en una nueva matriz que contenga las referencias a los modelos. Una forma es utilizar el método de clone guión bajo.

_.each(_.clone(collection.models), function(model) { model.destroy(); });


También podrías usar un buen, viejo estilo. popular destruir en el lugar:

var model; while (model = this.collection.first()) { model.destroy(); }