función de filtro de subrayado.js
Frecuentes
Visto 5,761 veces
3
Estoy intentando aprender backbone.js y (por extensión) underscore.js, y tengo algunas dificultades para entender algunas de las convenciones. Mientras escribía un filtro de búsqueda simple, pensé que algo como lo siguiente funcionaría:
var search_string = new RegExp(query, "i");
var results = _.filter(this, function(data){
return search_string.test(data.get("title"));
}));
Pero, de hecho, para que esto funcione, necesito cambiar mi función de filtro a lo siguiente:
var search_string = new RegExp(query, "i");
var results = _(this.filter(function(data){
return search_string.test(data.get("title"));
}));
Básicamente, quiero entender por qué funciona el segundo ejemplo, mientras que el primero no. Según la documentación (http://documentcloud.github.com/underscore/#filter), pensé que lo primero habría funcionado. O tal vez esto solo refleja algunos viejos hábitos míos de jQuery... ¿Alguien puede explicarme esto?
2 Respuestas
4
Supongo que estás usando un navegador con un nativo Array#filter
implementación. Pruebe esto en su consola y vea qué sucede:
[].filter.call({ a: 'b' }, function(x) { console.log(x) });
[].filter.call([1, 2], function(x) { console.log(x) });
El primero no hará nada, el segundo producirá 1
y 2
como salida (http://jsfiddle.net/ambiguous/tkRQ3/). el problema no es ese data
está vacío, el problema es que el nativo Array#filter
no sabe qué hacer cuando se aplica a un objeto que no es de matriz.
Todos los métodos de subrayado (incluyendo filter
) use las implementaciones nativas si están disponibles:
Delegados al nativo filtrar método, si existe.
Por lo tanto, los métodos Array-ish Underscore generalmente no funcionarán como _.m(collection, ...)
a menos que esté utilizando un navegador que no proporcione implementaciones nativas.
Una colección Backbone es un contenedor para una matriz de modelos, la matriz de modelos está en c.models
así que querrás:
_.filter(this.models, function(data) { ... });
Columna vertebral las colecciones tienen varios métodos de subrayado mezclado en:
Proxies de red troncal para Underscore.js para proporcionar 28 funciones de iteración en Backbone.Colección.
y uno de esos es filter
. Estos proxies aplican el método de subrayado a la matriz de modelos de la colección para que c.filter(...)
es el mismo que _.filter(c.models, ...)
.
Esta mezcla es probablemente lo que está confundiendo al "debo usar el método nativo" comprueba que Underscore está haciendo:
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
Puede usar el _.filter
en un objeto simple y viejo (_.filter({a:'b'}, ...)
) y obtiene resultados sensatos, pero falla cuando _.filter(backbone_collection, ...)
porque las colecciones ya tienen métodos de subrayado.
Aquí hay una demostración simple para aclarar las cosas: http://jsfiddle.net/ambiguous/FHd3Y/1/
contestado el 08 de mayo de 14 a las 20:05
Esto es exactamente lo que estaba buscando. Gracias por la excelente explicación. - bento
-1
Por la misma razón que $('#element')
trabaja y $#element
no lo hace _
es la variable global para el objeto de subrayado al igual que $
es la variable global para el jQuery
objeto.
_()
dice mira en el _
objeto. _filter
dice que busque un método llamado _filter
.
Respondido 01 Oct 12, 17:10
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas backbone.js filtering underscore.js or haz tu propia pregunta.
Debería decir _.filter; lo siento, fue un error tipográfico. Con _.filter, los datos están vacíos y, como resultado, "resultados" devuelve una matriz vacía. - bento
Y también debes
this
Qué es una colección Backbone? - mu is too shortSí lo es. Un console.log de (esto) me proporciona un "niño" con longitud, modelos, etc. - bento