Knockout2.x开发 第二十一章:使用fn实现扩展
2013-05-08 16:51 阅读(187)

前面文章讲述了observables扩展,其实与fn扩展相比,二者并无本质区别,只是某些参数上的使用有点异样。


对于上面的几个核心组件都可以使用fn扩展。

基本语法

ko.observable.fn.myExtend = function(myOption) {
    //do something ...
    return this;
}
仅以observable扩展为例。

如何使用

this. 属性名= ko.observable().myExtend("参数" );

下面还以observables扩展中示例演示,来对二者使用上的不同进行比较。


示例1:数据验证(validate)

Html代码

<p> 输入产品名称:
    <input data-bind='value: productName' />
	<span data-bind='visible: productName.hasError, text: productName.validationMessage'> </span>
</p>
Js代码
<script type="text/javascript">
ko.observable.fn.required = function(overrideMessage) {
    var target = this;
    //验证提示是否显示
	target.hasError = ko.observable();
	//验证提示信息
	target.validationMessage = ko.observable();
	
	//定义一个产品名称验证器,用于显示订阅
	function validate(newValue) {
	   target.hasError(newValue ? false : true);
	   target.validationMessage(newValue ? "" : overrideMessage);
	}
	
	//验证初始值
	validate(target());
	
	//添加订阅
	target.subscribe(validate);
	
	//原样返回依赖属性,即:ko.observable(productName)
	return target;
};
function AppViewModel(productName) {
    this.productName = ko.observable(productName).required("产品名称不能为空!" );
}
ko.applyBindings(new AppViewModel("HTC ONE"));
</script>

示例2:重写computed

Html代码

<p><input data-bind="value: myNumber" /> (round to whole number)</p>
Js代码
<script type="text/javascript">
ko.observable.fn.numeric = function(precision) {//precision:小数点后保留的位数
    var target = this;
    //创建一个依赖属性
	var result = ko.computed({
	    read: target, 
		write: function(newValue) {//重写write
		    var current = target(),
			    roundingMultiplier = Math.pow(10, precision),
				newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
				valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;//对输入进行四舍五入计算
			//输入值改变时,同步更新属性值
			if (valueToWrite !== current) {
			    target(valueToWrite);
			}
		}
	});
	
	//计算初始值的四舍五入值
	result(target());
	
	//返回创建的 computed observable
	return result;
};

function AppViewModel(myNumber) {
	this.myNumber = ko.observable(myNumber).numeric(2);
}
ko.applyBindings(new AppViewModel(221.225));
</script>