Метод на филтриране на Backbone Collection

Може ли някой да обясни механиката зад метода filter(), който съществува в „класа“ на колекцията? Backbone API за този метод изглежда несъвместим със следното примерно изпълнение (взето от упражнението Todo @ http://addyosmani.github.io/backbone-fundamentals/):

completed: function() {
    return this.filter(function( todo ) {
        return todo.get('completed');
    });
}

Този кодов фрагмент създава масив от моделни обекти, чието свойство „завършено“ съдържа „true“. Въпреки това не мога да се доближа до разбирането как масив от обекти се връща от тази функция


person Albert Chang    schedule 15.05.2013    source източник


Отговори (4)


Ключът към вашето любопитство се крие в изходния код с долни черти. Както вероятно вече знаете, голям брой методи, достъпни за вас в Backbone.Collection, се въвеждат от долната черта.

Нека първо да разгледаме как го правят:

// Underscore methods that we want to implement on the Collection.
// 90% of the core usefulness of Backbone Collections is actually implemented
// right here:
var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
'tail', 'drop', 'last', 'without', 'difference', 'indexOf', 'shuffle',
'lastIndexOf', 'isEmpty', 'chain'];

// Mix in each Underscore method as a proxy to `Collection#models`.
_.each(methods, function(method) {
    Collection.prototype[method] = function() {

      // Important: BOLT ON THE COLLECTION MODELS TO THE ARGUMENTS.
      var args = slice.call(arguments);
      args.unshift(this.models);

      // .apply (since we have an array of arguments).
      return _[method].apply(_, args);
    };
});

Така че имаме списък с имена на методи за подчертаване. Изходният код преминава през тези имена на методи и добавя всяко едно към прототипа на вашите колекции. Важно: Ще забележите, че този код коригира списъка с аргументи, за да го включи в моделите на вашата колекция.

Сега вижте действителното внедряване на метода на подчертаване:

_.filter = _.select = function(obj, iterator, context) {
  var results = [];
  if (obj == null) return results;
  if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);

  each(obj, function(value, index, list) {
    if (iterator.call(context, value, index, list)) results.push(value);
  });

  return results;
}

Ще забележите, че филтърът просто обгръща всеки и преминава през предавания обект (свойства). Всичко, което основната версия прави, е да постави този метод в контекст, за да ви спести необходимостта да предавате моделите всеки път.

person backdesk    schedule 12.12.2013

return todo.get('completed');

основно съответства на това

return todo.get('completed') === true ;

Така че всички todo Models в колекцията, целият атрибут completed е зададен на true ще бъде върнат от най-вътрешния оператор за връщане

И най-външното връщане ще върне колекцията от всички модели, чието условие е удовлетворено от филтърната функция.

Това може просто да се напише като

completed: function() {
    var filteredModels =  this.filter(function( todo ) {
        return todo.get('completed');
    });

    return filteredModels;
}
person Sushanth --    schedule 15.05.2013

Методът на филтъра създава празен масив за резултати и преминава през this.models. И ако функцията iterator върне истинска стойност, моделът се избутва към масива с резултати. Във вашия пример iterator е

function (todo) {
  return todo.get('completed');
}

iterator връща някаква стойност, която е проверена за вярна

// simplified call
if (iterator()) results.push(value)
person Vitalii Petrychuk    schedule 15.05.2013

тук завършената функция е филтрираща функция за показване само на завършената задача

Тъй като гръбнакът продължава подчертаването тук

филтрираният метод на undescore се извиква, което обикновено го прави

filter_.filter(list, iterator, [context]) Alias: select 

Преглежда всяка стойност в списъка, връщайки масив от всички стойности, които преминават тест за истинност (итератор). Делегира метода на основния филтър, ако съществува.

Това означава, че todo.get се предава на всеки модел в колекцията и това е за тестване на всеки модел за тяхното завършено състояние, ако е вярно, че моделът се връща в масива на функцията

person Pascal    schedule 18.10.2013
comment
Моля, обърнете внимание, че отговорите ви трябва да се отнасят до конкретния въпрос, зададен директно; не просто предоставя блок от код, който изглежда прави това, което питащият иска. - person Andrew Barber; 18.10.2013