我正在写angularjs模型服务。但是我想要一些方便的方法来设置默认值和嵌套模型。
这是我到达的解决方案。
var Model = function () { this.assign = function (obj, members_to_set) { if (typeof obj !== 'undefined') { angular.forEach(members_to_set, function (member, index) { if (typeof obj[member] !== 'undefined') { this[member] = obj[member]; } }, this); } }; this.assignList = function (member, obj, setter, default_) { this[member] = []; if (typeof obj !== 'undefined' && typeof obj[member] !== 'undefined') { angular.forEach(obj[member], function (val, index) { this[member].push(setter(val)); }, this); } else { this[member].push(default_); } }; }
使用它
var Car = function(car_data){ var defaults = { make: '', year: '', manufacturer: '' } this.assign(defaults, ['make', 'year']); this.assign(car_data, ['make', 'year']); //Similarly this.assignList('owners', car_data, function(owner_data){ return new Owner(owner_data); }, new Owner()} } Car.prototype = new Model();
但我确信这些问题已经得到了解,并且有很好理解的解决方案。我不想重新发明这个特殊的轮子。
因此,问题是:有更好的方法吗?
答案 0 :(得分:1)
可能有一些图书馆可以帮助解决这个问题,但是这些图书馆可能还会附带大量您不需要的功能。
必须应用默认值可能是许多类型对象的关注点,因此我会在其自己的函数中提取行为,然后可以从Model
中使用该行为,而不是将其作为{{1}的一部分} class logic。
此外,如果您希望提高内存效率,则应在所有实例之间共享默认值,而不是在每个实例上复制默认值。因此,我们避免使用Model
。
我遗漏了任何模块化以保持示例简单,但您应该模块化您的代码!
angular.extend
现在,对于//only extend when properties have a different value
function diffExtend(obj, data, keys) {
(keys || Object.keys(data)).forEach(function (k) {
if (obj[k] !== data[k]) obj[k] = data[k];
});
return obj;
}
//Base class for every models
function Model(data, keys) {
diffExtend(this, data, keys);
}
//Concrete Car model
function Car(data) {
//only copy over make and year, but we could avoid passing keys to copy everything
Model.call(this, data, ['make', 'year']);
}
Car.prototype = diffExtend(Object.create(Model.prototype), {
constructor: Car,
//default values (only for primitives because these aren't mutable)
make: 'default make',
year: 2000
});
//instanciate a new car
var c = new Car({ make: 'test', year: 2000, invalidProperty: true });
c.make; //test
c.year; //2000
c.hasOwnProperty('make'); //true
c.hasOwnProperty('year'); //false because it's on the prototype
c.invalidProperty; //undefined
功能,您只需使用assignList
。
E.g。
Array.prototype.map
也许我没有为您想要的提供全面的解决方案,但我相信您现在应该具备实施完全符合您需求的高效解决方案所需的知识。
答案 1 :(得分:0)
常用方法是使用extend
设置默认值。角度,jquery,下划线以及许多其他库都支持extend
。
用法很简单
function Foo(defaults){
this.a = 10;
this.b = 11;
angular.extend(this, defaults);
}
然后,当你创建一个Foo:
var f = new Foo({a:100, c:200, d: {d1:100, d2:200}});
console.log(f);
// Foo {a: 100, b: 11, c: 200, d: Object}
请参阅:http://plnkr.co/edit/qRJRj8YfetSIcbRpxBc5?p=preview
但这比你想要的要复杂得多。我希望这会有所帮助。