Backbone Collection过滤方法

时间:2013-05-15 04:13:15

标签: javascript backbone.js collections filtering

有人可以解释Collection“类”中存在的filter()方法背后的机制吗?此方法的Backbone API似乎与以下示例实现不一致(取自Todo练习@ http://addyosmani.github.io/backbone-fundamentals/):

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

此代码段生成一个模型对象数组,其“已完成”属性包含“true”。但是,我无法理解如何从此函数返回一个对象数组

4 个答案:

答案 0 :(得分:1)

好奇心的关键在于强调源代码。您可能已经知道,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;
}

您会注意到过滤器只是环绕每个过滤器并循环传入的对象(属性)。所有骨干版本都将此方法放入上下文中,以免您每次都必须传入模型。

答案 1 :(得分:0)

return todo.get('completed');

基本上对应于此

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

所以集合整体属性已完成中的所有todo Models都设置为 true 将从最里面的return语句返回

最外面的返回将返回过滤函数满足条件的所有模型的集合。

这可以简单地写成

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

    return filteredModels;
}

答案 2 :(得分:0)

Filter方法为结果创建空数组并循环遍历this.models。如果iterator函数返回真值,则模型将被推送到结果数组。 在您的示例中,iterator

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

iterator返回一些真值检查的值

// simplified call
if (iterator()) results.push(value)

答案 3 :(得分:-1)

这里完成的功能是一个过滤功能,只显示已完成的待办事项

由于骨干在这里扩展了下划线

调用非核心的过滤方法,通常

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

查看列表中的每个值,返回通过真值测试(迭代器)的所有值的数组。委托自然过滤器方法(如果存在)。

意味着todo.get在集合中的每个模型上传递,这是为了测试每个模型的完成状态,如果为真,则模型在函数数组中返回

相关问题