好久没在首页发点东西了,昨天在上依照wpf中依赖属性的思想尝试写了基本的功能.这里拿出来与大家分享
Demo1 注册依赖属性
step1 定义一个函数
function Person() {
this.render = function () { }
};
step2 注册依赖属性
第三个参数是属性变更回调
dp.reg(Person, "name", "terry", function (obj) {
obj.render();
alert(obj.oldValue);
alert(obj.newValue);
});
setp3 修改依赖属性值
上面的回调方法触发了,至于具体这个功能用在什么场合,你懂的
dp.setValue(entity, "name", "zhang");
Demo2 注册只读依赖属性
下面的回调方法将会触发
dp.regReadOnly(Person, "sex", "boy", function (obj) {
alert(obj.newValue);
});
另外还可以添加一个属性验证回调,如下,因为年龄不可能小于0
dp.reg(Person, "age", 25, function (obj) {
}, function (value) {
if (value < 1)
return 1;
return value;
});
Demo3 读写依赖属性
用setValue和getValue方法
var entity = new Person();
dp.getValue(entity, "age")
dp.setValue(entity, "name", "xinghao");
Demo4 默认属性值
在注册依赖属性时就有一个默认的值,可通过下面方法查看和恢复默认值
dp.getDefaultValue(entity, "name");
dp.clearValue(entity, "name");
Demo5 注销依赖属性
dp.unreg("Person", "name");
说明:以上通过依赖属性注册的属性不会存在原有对象中,即注册了Person,但不会影响Person本身对象.那么久是说依赖属性是一个可插拔的功能.如果你还没有过这种属性定义的尝试的话,那么来试一下吧。我将继续完善其功能,并与大家分享(假设你还没有依赖属性的概念,也可以尝尝鲜)
最后奉上完整代码,尚未完善,大家提意见吧
(function (container) {
var ORIGINAL_TYPE = "originalType",
PREFIX = "dp"
//utility
function getPropName(obj) {
return PREFIX + obj.originalType;
}
function getFnName(obj) {
var fundoc = obj.prototype ? obj.toString() : obj.constructor.toString(),
funcName = fundoc.split('(')[0].split(' ')[1];
return funcName;
}
var dpos = [];
container.dp = {};
function propertyMetadata(propertyName, defaultValue, propertyChangedCallback) {
this.PropertyName = propertyName;
this.DefaultValue = defaultValue;
this.PropertyChangedCallback = propertyChangedCallback;
};
propertyMetadata.prototype = {
PropertyName: "",
isReadOnly: false,
Value: undefined,
DefaultValue: undefined,
CoerceValueCallback: undefined,
PropertyChangedCallback: function () { }
};
function dpObject(entity) {
this.objectType = entity;
this.dmps = {};
};
dpObject.prototype = {
addDmp: function (propertyName, defaultValue, propChanged, coerceValueCallback) {
if (this.dmps[propertyName]) return;
var dmp = new propertyMetadata(propertyName, defaultValue, propChanged);
dmp.CoerceValueCallback = coerceValueCallback;
this.dmps[propertyName] = dmp;
return dmp;
},
getDmpCount: function () {
return this.dmps.lenth;
},
getPropValue: function (propertyName,prop) {
var dmp = this.dmps[propertyName];
return dmp[prop];
},
getDmp: function (propertyName) {
return this.dmps[propertyName];
},
clearDmp: function (propertyName) {
this.dmps[propertyName] = undefined;
delete this.dmps[propertyName];
},
setValue: function (obj, prop, newValue) {
var dmp = this.dmps[prop];
if (!dmp || dmp.isReadOnly) return;
var oldValue = dmp.Value || dmp.DefaultValue;
if (dmp.CoerceValueCallback)
newValue = dmp.CoerceValueCallback(newValue);
if (newValue !== oldValue)
dmp.Value = newValue;
if (dmp.PropertyChangedCallback) {
var changedArgs = { obj: obj, prop: prop, oldValue: oldValue, newValue: newValue }
dmp.PropertyChangedCallback(changedArgs);
}
},
getValue: function (prop) {
var dmp = this.dmps[prop];
return dmp.Value ? dmp.Value : dmp.DefaultValue;
},
getDefaultValue: function (prop) {
var dmp = this.dmps[prop];
return dmp.DefaultValue;
},
clearValue: function (prop) {
var dmp = this.dmps[prop];
dmp.Value = undefined;
}
};
dp.unReg = function (obj, prop) {
var className = getFnName(obj),
dpo = dpos[className];
dpo.clearDmp(prop);
};
dp.isReged = function (obj, prop) {
var className = getFnName(obj),
dpo = dpos[className];
if (!prop)
return dpo.getDmpCount() > 0;
return dpo.getDmp(prop) == undefined;
};
dp.isReadOnly=function(obj,prop) {
var dpo = getDpo(obj);
return dpo.getPropValue(prop, "isReadOnly");
};
dp.reg = function (obj, prop, value, propChanged, coerceValueCallback, isReadOnly) {
var className = getFnName(obj),
dpo = dpos[className] = dpos[className] || new dpObject(className);
dpo.addDmp(prop, value, propChanged, coerceValueCallback);
if (isReadOnly) {
var dmp = dpo.getDmp(prop);
dmp.isReadOnly = true;
}
};
dp.regReadOnly = function (obj, prop, value, propChanged, coerceValueCallback) {
dp.reg(obj, prop, value, null, null, true);
};
function getDpo(obj) {
var className = getFnName(obj),
dpo = dpos[className];
return dpo;
};
dp.setValue = function (obj, prop, value) {
var dpo = getDpo(obj);
dpo.setValue(obj, prop, value);
};
dp.getValue = function (obj, prop) {
var dpo = getDpo(obj);
return dpo.getValue(prop, value);
};
dp.getDefaultValue = function (obj, prop) {
var dpo = getDpo(obj);
return dpo.getDefaultValue(prop);
};
dp.clearValue = function (obj, prop) {
var dpo = getDpo(obj);
dpo.clearValue(prop);
};
})(window);
function Person() {
this.render = function () { }
};
dp.reg(Person, "name", "terry", function (obj) {
obj.render();
alert(obj.oldValue);
alert(obj.newValue);
});
dp.setValue(entity, "name", "zhang");
dp.reg(Person, "age", 25, function (obj) {
}, function (value) {
if (value < 1)
return 1;
return value;
});
dp.regReadOnly(Person, "sex", "boy", function (obj) {
alert(obj.newValue);
});
dp.setValue(entity, "age", -1);
var entity = new Person();
dp.getValue(entity, "age")
dp.setValue(entity, "name", "xinghao");
alert(dp.isReged(entity);
alert(dp.getValue(entity, "name"));
dp.getDefaultValue(entity, "name");
dp.clearValue(entity, "name");
alert(dp.getValue(entity, "name"));
dp.unreg("Person", "name");
dp.setValue(entity, "name", "zhang");