Knockout自定义绑定创建方法


Posted in Javascript onDecember 26, 2015

概述

除了上一篇列出的KO内置的绑定类型(如value、text等),你也可以创建自定义绑定。

注册你的binding handler

ko.bindingHandlers.yourBindingName = {
  init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    // 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, valueAccessor, allBindings, viewModel, bindingContext) {
    // This will be called once when the binding is first applied to an element,
    // and again whenever any observables/computeds that are accessed change
    // Update the DOM element based on the supplied values here.
  }
};

接下来你就可以在任意dom元素上使用的自定义绑定了:

<div data-bind="yourBindingName: someValue"> </div>

注意:你不必在你的handler里把init和update的callback都提供,可以提供任意一个。

update callback

顾名思义,当你的监控属性observable更新的时候,ko会自动调用你的update回调。

它有以下参数:

    element:使用这个绑定的dom元素;

    valueAccessor  : 通过调用valueAccessor()可以获得当前绑定的model属性值,调用ko.unwrap(valueAccessor())能够更方便的获取observable的值和普通值;

    allBindings : 绑定到这个dom元素上的model的所有属性值,例如调用callBindings.get('name') 返回绑定的name属性值(不存在返回undefined),或者调用allBindings.has('name')判断name是否绑定到了当前的dom中;

    viewModel  : 在Knockout.3x中以弃用,可用bindingContext.$data或者bindingContext.$rawData来获取当前的viewModel;

   bindingContext  : 绑定上下文,可调用bindingContext.$data、 bindingContext.$parent, bindingContext.$parents等获取数据;

接下来看一个例子,你也许希望使用visible绑定来控制元素的可见性,并且加上动画效果,这时你可以创建你的自定义绑定:

ko.bindingHandlers.slideVisible = {
  update: function(element, valueAccessor, allBindings) {
    // First get the latest data that we're bound to
    var value = valueAccessor();
    // Next, whether or not the supplied model property is observable, get its current value
    var valueUnwrapped = ko.unwrap(value);
    // Grab some more data from another binding property
    var duration = allBindings.get('slideDuration') || 400; // 400ms is default duration unless otherwise specified
    // Now manipulate the DOM element
    if (valueUnwrapped == true)
      $(element).slideDown(duration); // Make the element visible
    else
      $(element).slideUp(duration);  // Make the element invisible
  }
};

然后你可以这样使用这个自定义绑定:

<div data-bind="slideVisible: giftWrap, slideDuration:600">You have selected the option</div>
<label><input type="checkbox" data-bind="checked: giftWrap" /> Gift wrap</label>
<script type="text/javascript">
  var viewModel = {
    giftWrap: ko.observable(true)
  };
  ko.applyBindings(viewModel);
</script>

init callback

ko将为每个使用绑定的dom元素调用你的init函数,它有两个主要用途:

(1)为dom元素设置初始化状态;

(2)注册一些事件处理程序,例如:当用户点击或者修改dom元素时,你可以改变监控属性的状态;

ko将使用和update回调完全相同一组参数。

继续前面的例子,你也许想让slideVisible在页面第一次显示的时候就设置该元素的可见性状态(没有任何动画效果),而动画效果是在以后改变的时候执行,你可以按照下面的方式来做:

ko.bindingHandlers.slideVisible = {
  init: function(element, valueAccessor) {
    var value = ko.unwrap(valueAccessor()); // Get the current value of the current property we're bound to
    $(element).toggle(value); // jQuery will hide/show the element depending on whether "value" or true or false
  },
  update: function(element, valueAccessor, allBindings) {
    // Leave as before
  }
};

giftWrap被初始化定义为false(ko.observable(false)),关联的DIV会在初始化的时候隐藏,之后用户点击checkbox时才让DIV显示。

你现在已经知道如何使用update回调了,当observable值改变的时候你可以更新dom元素。我们现在可以用另外的方法来做,比如当用户有某个action操作时,也能引起你的observable值更新,例如:

ko.bindingHandlers.hasFocus = {
  init: function(element, valueAccessor) {
    $(element).focus(function() {
      var value = valueAccessor();
      value(true);
    });
    $(element).blur(function() {
      var value = valueAccessor();
      value(false);
    });
  },
  update: function(element, valueAccessor) {
    var value = valueAccessor();
    if (ko.unwrap(value))
      element.focus();
    else
      element.blur();
  }
};

现在你可以通过元素的“focusedness”绑定来读写你的observable值了。

<p>Name: <input data-bind="hasFocus: editingName" /></p>
<!-- Showing that we can both read and write the focus state -->
<div data-bind="visible: editingName">You're editing the name</div>
<button data-bind="enable: !editingName(), click:function() { editingName(true) }">Edit name</button>
<script type="text/javascript">
  var viewModel = {
    editingName: ko.observable()
  };
  ko.applyBindings(viewModel);
</script>

以上内容是小编给大家分享的Knockout自定义绑定创建方法,希望大家喜欢。

Javascript 相关文章推荐
比较详细的关于javascript 解析json的代码
Dec 16 Javascript
匹配任意字符的正则表达式写法
Apr 29 Javascript
javascript中检测变量的类型的代码
Dec 28 Javascript
angular.element方法汇总
Jan 07 Javascript
javascript实现表单提交后,提交按钮不可用的方法
Apr 18 Javascript
js闭包所用的场合以及优缺点分析
Jun 22 Javascript
JS判断是否长按某一键的方法
Mar 02 Javascript
手机图片预览插件photoswipe.js使用总结
Aug 25 Javascript
web3.js增加eth.getRawTransactionByHash(txhash)方法步骤
Mar 15 Javascript
JavaScript中发出HTTP请求最常用的方法
Jul 12 Javascript
微信小程序版本自动更新的方法
Jun 14 Javascript
浅谈layui框架自带分页和表格重载的接口解析问题
Sep 11 Javascript
JavaScript动态设置div的样式的方法
Dec 26 #Javascript
JS插件overlib用法实例详解
Dec 26 #Javascript
如何解决easyui自定义标签 datagrid edit combobox 手动输入保存不上
Dec 26 #Javascript
认识Knockout及如何使用Knockout绑定上下文
Dec 25 #Javascript
详解Document.Cookie
Dec 25 #Javascript
不得不分享的JavaScript常用方法函数集(下)
Dec 25 #Javascript
JQuery datepicker 用法详解
Dec 25 #Javascript
You might like
PHP数组操作――获取数组最后一个值的方法
2015/04/14 PHP
php里array_work用法实例分析
2015/07/13 PHP
tp5框架基于ajax实现异步删除图片的方法示例
2020/02/10 PHP
网页和浏览器兼容性问题汇总(draft1)
2009/06/01 Javascript
JS/FLASH实现复制代码到剪贴板(兼容所有浏览器)
2013/05/27 Javascript
JavaScript中的eval()函数详解
2013/08/22 Javascript
Jquery Validate 正则表达式实用验证代码大全
2013/08/23 Javascript
JQuery菜单效果的两个实例讲解(3)
2015/09/17 Javascript
javaScript实现可缩放的显示区效果代码
2015/10/26 Javascript
详解Javascript事件驱动编程
2016/01/03 Javascript
原生JS实现风箱式demo,并封装了一个运动框架(实例代码)
2016/07/22 Javascript
浅谈js中子页面父页面方法 变量相互调用
2016/08/04 Javascript
使用HTML5+Boostrap打造简单的音乐播放器
2016/08/05 Javascript
js实现StringBuffer的简单实例
2016/09/02 Javascript
Django中使用jquery的ajax进行数据交互的实例代码
2017/10/15 jQuery
js 客户端打印html 并且去掉页眉、页脚的实例
2017/11/03 Javascript
小程序显示弹窗时禁止下层的内容滚动实现方法
2019/03/20 Javascript
详解Vue中使用Axios拦截器
2019/04/22 Javascript
Vue-Cli 3.0 中配置高德地图的两种方式
2019/06/19 Javascript
vue.js+elementUI实现点击左右箭头切换头像功能(类似轮播图效果)
2019/09/05 Javascript
jquery实现商品sku多属性选择功能(商品详情页)
2019/12/20 jQuery
[20:30]职业巡回赛回顾
2018/08/09 DOTA
django中forms组件的使用与注意
2019/07/08 Python
python+numpy按行求一个二维数组的最大值方法
2019/07/09 Python
Python使用Opencv实现图像特征检测与匹配的方法
2019/10/30 Python
python各种excel写入方式的速度对比
2020/11/10 Python
HTML5离线缓存Manifest是什么
2016/03/09 HTML / CSS
Linux如何命名文件--使用文件名时应注意
2012/01/22 面试题
成人毕业生自我鉴定
2013/10/18 职场文书
农村葬礼主持词
2014/03/31 职场文书
工作求职自荐信
2014/06/13 职场文书
院党委组织查摆问题对照检查材料思想汇报2014
2014/10/08 职场文书
经营场所证明范本
2015/06/19 职场文书
浅谈Python 中的复数问题
2021/05/19 Python
Django migrate报错的解决方案
2021/05/20 Python
Java Dubbo框架知识点梳理
2021/06/26 Java/Android