SOLUTION TO MY ORIGINAL QUESTION
Thanks to the brilliance of Dan's answer below I've managed to reduce my original code significantly. I have dropped some of flexibility I originally had built i.e. use multi properties vs static prop, but an easy fix in a later version and a no-brainer in terms of code size :) Again, many thanks to Dan. In this example I've included 2 forget()
methods wrapped in an Angular Collection factory.
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;
};
DEV TOOLS
Angular 1.4.8, lodash 2.x
QUESTION:
I'm still an Angular & JS. Is there a more concise approach to deleting multiple object instances (e.g. Article/s in a Articles Collection). The forget()
method accepts 1 argument that could a string||integer||array (of strings or integers)
EXAMPLE:
var articleIdsToRemove = [1, '2', 3];
OR
var articleIdsToRemove = 1;
var articles = newCollection();
For brevity sake i've excluded the add method for adding Article instances to collection but lets assume we have 10, each with a prop of id
MY CURRENT APPROACH
ids
Article
instance that has prop id
and is equal to value id
Array.prototype.remove
to remove multiple
items from the collection array. Once that is done then re-sort
collectionremoved Angular factory wrapper for brevity sake, but assume all of this is in a angular factory called Collection which injects an Article factory that is data model. In summary Collection
(articles) contains many 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);
}
};
Take a look at this
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);
});
}
Example here: http://jsfiddle.net/hFm7j/226/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With