función de filtro de subrayado.js

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?

preguntado el 22 de mayo de 12 a las 21:05

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. -

Y también debes this Qué es una colección Backbone? -

Sí lo es. Un console.log de (esto) me proporciona un "niño" con longitud, modelos, etc. -

2 Respuestas

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

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 or haz tu propia pregunta.