Angular / lodash - 从集合中删除多个对象

5

我原问题的解决方案

多亏了下面Dan的出色答案,我成功地将原来的代码大幅缩减。我放弃了一些最初拥有的灵活性,即使用多个属性而不是静态属性,但这是一个稍后版本的易修复问题,对于代码大小来说是一个显而易见的选择。再次感谢Dan。在这个例子中,我包含了两个forget()方法,这些方法被包裹在一个Angular Collection工厂中。

Collection.$inject = ['Constructor', 'Article'];
function Collection(Constructor, Article) {

    var Model = Article,
        Collection = {},
        collection = [],
        add,
        forget;

    function Extendable(data, keys) {
        Constructor.call(this, data, Model.fillable);
    }

    Extendable.prototype = Object.create(Constructor.prototype);
    Extendable.prototype.constructor = Extendable;
    Collection = Extendable.prototype;
    collection = Collection.items = [];

    add = function(item) {
        if (item instanceof Model) {
            collection.push(item);
        }
    };
    Collection.add = add;

    // EXAMPLE OF SINGLE ID DELETE I.E. SIMPLE VERSION
    forget = function(id) {
        collection = _.dropWhile(collection, {id: id});
    };
    Collection.forget = forget;

    // OR!!! EXAMPLE OF MULTI ID VALUE || ARRAY
    forget = function(id) {
        var ids = [];
        if (_.isArray(id)) {
            ids = id;
        } else {
            ids.push(parseInt(id));
        }
        return _.dropWhile(collection, function (n) {
            return _.includes(ids, n.id);
        });
    };
    Collection.forget = forget;

    // remove rest of factory for brevity sake
    return Extendable;
};

开发工具

Angular 1.4.8, lodash 2.x

问题:

我仍在学习 Angular 和 JS。是否有更简洁的方法来删除多个对象实例(例如,Articles 集合中的 Article/s)。forget() 方法接受 1 个参数,可以是字符串、整数或字符串或整数的数组。

示例:

var articleIdsToRemove = [1, '2', 3];

或者

var articleIdsToRemove = 1; 

var articles = newCollection();

为了简洁起见,我省略了向集合中添加文章实例的add方法,但假设我们有10个这样的实例,每个实例都有一个id属性。

我的当前方法

  1. 验证值的类型,如上所述即数组、字符串、整数,并将所有值设置为int类型的数组,即ids
  2. 然后遍历id数组,找到Article实例的索引,该实例具有prop id,并且等于id的值
  3. 如果找到,则将索引推入indices数组。一旦我们有所有匹配的索引,就将其发送给Array.prototype.remove以从集合数组中删除多个项。完成后重新对集合进行排序

出于简洁起见,我省略了Angular工厂包装器,但假设所有内容都在名为Collection的Angular工厂中,该工厂注入了一个数据模型是Article的Article工厂。总之,Collection (articles) 包含许多Article

    // We set a collections array inside of object to hold all Article instances
    collection = Extendable.prototype.items = [];
    // NOTE add articles method removed, but assume weve added multiple Article's to collection 

    forget = function(id) {
        var ids = [],
            index = null,
            indices = [];
        if (angular.isDefined(id) && !_.isEmpty(id)) {
            ids = _.isArray(id) ? id : isInt(id) ? [Number(id)] : [];
            if (ids.length) {
                _.each(ids, function(id) {
                    index = getIndex('app_id', id);
                    if (index) {
                        indices.push(index)
                    }
                });
                if (indices.length) {
                    collection = collection.remove(indices)
                }
            }
        }
    };
    Extendable.prototype.forget = forget;

    function isInt(n){
        return Number(n) === n && n % 1 === 0;
    }

    function getIndex(prop, value) {
        return _.indexOf(collection, function(d) {
            if (hasProp(d, prop)) {
                return d[prop] == value;
            }
        });
    }

    function hasProp (obj, prop) {
        return Object.prototype.hasOwnProperty.call(obj, prop);
    }

    Array.prototype.remove = function(){
        var args = Array.apply(null, arguments);
        var indices = [];
        for(var i = 0; i < args.length; i++){
            var arg = args[i];
            var index = this.indexOf(arg);
            while(index > -1){
                indices.push(index);
                index = this.indexOf(arg, index + 1);
            }
        }
        indices.sort();
        for(var i = 0; i < indices.length; i++){
            var index = indices[i] - i;
            this.splice(index, 1);
        }
    };
1个回答

2

看看这个

var forget = function(id) {
  var ids = [];
  if (_.isArray(id)) {
    ids = id;
  } else {
    ids.push(parseInt(id));
  }
  return _.dropWhile(articles, function(n) {
    return _.includes(ids, n.id);
  });
}

这里有一个示例:http://jsfiddle.net/hFm7j/226/

这样做只会在条件返回 false 时删除一个元素,如果数组是由用户选择文章构建的,那么 id 可能是无序的,因此在你的例子中调用 forget(['4',3']) 不会删除任何内容。我认为使用 _.reject 更合适,而不是 _.dropWhile - steezeburger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接