KnockoutJS-自定义属性绑定
在knockoutjs中,已有的绑定功能已经十分强大,基本上可以不需要再去考虑扩展了,但是,也有例外的场景,面对这种场景,还是得去完成,knockoutJS提供了自定义绑定来扩展绑定功能。 ? 一、新建绑定新建一个js文件来尝试绑定功能,按照给定的格式ko.bindingHandlers.xxx来扩展一个绑定。 ko.bindingHandlers.yourBindingName = { init: function(element,valueAccessor,allBindingsAccessor,viewModel) { // This will be called when the binding is first applied to an element // Set up any initial state,event handlers,etc. here },update: function(element,viewModel) { // This will be called once when the binding is first applied to an element, // and again whenever the associated observable changes value. // Update the DOM element based on the supplied values here. } }; ? 其次,在html中完成绑定即可,用法同自带的绑定。 <div data-bind="yourBindingName: someValue"> </div> 此处需要注意的是,在自定义绑定中,init和update方法不是一定要全部定义,也可以只定义其中一个。 最后将js文件引入,放置在knockoutjs下 <script src="~/lib/knockout/knockout-3.5.0.js"></script> <script src="~/js/custombindings.js" asp-append-version="true"></script> ? 二、解析update函数当绑定的监听元素的发生改变时或是关联的监听元素改变时,knockout会回调update函数,只要存在关联的监听元素改变,update函数都会被立马回调,回调时会传递几个参数到update函数中。
例如,你可能想通过 visible绑定来控制一个元素的可见性,但是你想让该元素在隐藏或者显示的时候加入动画效果。那你可以自定义自己的绑定来调用jQuery的slideUp/slideDown 函数: ko.bindingHandlers.slideVisible = { update: function(element,allBindings) { // 获取属性值 var value = valueAccessor(); // 获取当前属性值 var valueUnwrapped = ko.unwrap(value); // 从当前绑定上下文的其它上下文获取属性值 var duration = allBindings.get(‘slideDuration‘) || 400; // 400ms is default duration unless otherwise specified // 操控DOM元素 if (valueUnwrapped == true) $(element).slideDown(duration); // Make the element visible else $(element).slideUp(duration); // Make the element invisible } }; ? 页面上,直接按照格式完成绑定,此处,我将自定义文件已经引入到模板页的js块中。 <div data-bind="slideVisible: giftWrap,slideDuration: 600">You have selected the option</div> <label><input type="checkbox" data-bind="checked: giftWrap" /> Gift wrap</label> @section Scripts{ <script type="text/javascript"> var viewModel = { giftWrap: ko.observable(true) }; $(function () { ko.applyBindings(viewModel);//完成绑定 }); </script> } ? 可以看到自定义绑定的效果,可以在多处地方完成绑定以实现代码重用。 三、解析init函数knockout在DOM元素使用自定义绑定的时候会调用你的init函数,init函数主要有两个用途:
init函数接收和update函数一样的参数,按照上面的例子,改造一下,让slideVisible在页面第一次显示的时候设置该元素的状态(但是不使用任何动画效果),以便于让动画在以后用户改变的时候再执行。 ko.bindingHandlers.slideVisible = { init: function (element,valueAccessor) { var value = ko.unwrap(valueAccessor()); $(element).toggle(value); },update: function (element,allBindings) { // 获取属性值 var value = valueAccessor(); // 获取当前属性值 var valueUnwrapped = ko.unwrap(value); // 从当前绑定上下文的其它上下文获取属性值 var duration = allBindings.get(‘slideDuration‘) || 400; // 400ms is default duration unless otherwise specified // 操控DOM元素 if (valueUnwrapped == true) $(element).slideDown(duration); // Make the element visible else $(element).slideUp(duration); // Make the element invisible } }; ? 将viewModel中的giftWrap设置默认值为false,当页面启动后将会看见相应的Div直接是隐藏状态,并在点击选中后才会显示出来。 var viewModel = { giftWrap: ko.observable(true) }; ? 四、DOM事件后修改监听值已经掌握了使用update回调当observable值改变的时更新DOM元素。但是反过来的场景呢,例如当用户对某个DOM元素做一些操作时,想更新相关的observable值。这可以通过使用init回调来注册一个事件句柄,来改变相关的observable值。 ko.bindingHandlers.hasFocus = { init: function (element,valueAccessor) { $(element).focus(function () { var value = valueAccessor(); value(true); }); $(element).blur(function () { var value = valueAccessor(); value(false); }); },valueAccessor) { var value = valueAccessor(); if (ko.unwrap(value)) element.focus(); else element.blur(); } }; 比如,当用户点击输入框时展示,离开时隐藏,同时修改监听值,控制按钮的启用禁用。 <p>Name: <input data-bind="hasFocus: editingName" /></p> <div data-bind="visible: editingName">You‘re editing the name</div> <button data-bind="enable: !editingName(),click:function() { editingName(true) }">Edit name</button> @section Scripts{ <script type="text/javascript"> var viewModel = { giftWrap: ko.observable(false),editingName: ko.observable() }; $(function () { ko.applyBindings(viewModel);//完成绑定 }); </script> } 可以得到如下效果
在虚拟元素上也可以使用自定义绑定 <!-- ko mybinding: somedata --> ... <!-- /ko --> ? 至此,完成了自定义绑定的方式,虽然实际使用的少,诸如二八原则,但是只要存在场景便可以发挥用武之地。 代码地址:https://gitee.com/530521314/Partner.TreasureChest.git ? 2019-08-29,望技术有成后能回来看见自己的脚步
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |