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跑马灯悬停放大效果实现代码
Dec 12 Javascript
jQuery基于$.ajax设置移动端click超时处理方法
May 14 Javascript
jquery实现的table排序功能示例
Mar 10 Javascript
jQuery操作之效果详解
May 19 jQuery
Vue路由跳转问题记录详解
Jun 15 Javascript
js禁止浏览器页面后退功能的实例(推荐)
Sep 01 Javascript
Angular2里获取(input file)上传文件的内容的方法
Sep 05 Javascript
新手快速上手webpack4打包工具的使用详解
Jan 28 Javascript
koa2 从入门到精通(小结)
Jul 23 Javascript
解决vue v-for src 图片路径问题 404
Nov 12 Javascript
Vue数据双向绑定底层实现原理
Nov 22 Javascript
浅谈关于vue中scss公用的解决方案
Dec 02 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中理解print EOT分界符和echo EOT的用法区别小结
2010/02/21 PHP
JavaScript 私有成员分析
2009/01/13 Javascript
Prototype Hash对象 学习
2009/07/19 Javascript
jquer之ajaxQueue简单实现代码
2011/09/15 Javascript
常见的原始JS选择器使用方法总结
2014/04/09 Javascript
Javascript中的方法和匿名方法实例详解
2015/06/13 Javascript
jQuery编程中的一些核心方法简介
2015/08/14 Javascript
Javascript中replace()小结
2015/09/30 Javascript
浅析JavaScript中的变量复制、参数传递和作用域链
2016/01/13 Javascript
javascript 中null和undefined区分和比较
2017/04/19 Javascript
javascript实现Emrips反质数枚举的示例代码
2017/12/06 Javascript
js对象数组和对象的使用实例详解
2019/08/27 Javascript
浅谈vue中组件绑定事件时是否加.native
2019/11/09 Javascript
angula中使用iframe点击后不执行变更检测的问题
2020/05/10 Javascript
vue 保留两位小数 不能直接用toFixed(2) 的解决
2020/08/07 Javascript
Python实现简单的获取图片爬虫功能示例
2017/07/12 Python
python中利用Future对象异步返回结果示例代码
2017/09/07 Python
Python面向对象之继承和组合用法实例分析
2018/08/27 Python
使用Python实现 学生学籍管理系统
2019/11/26 Python
Keras - GPU ID 和显存占用设定步骤
2020/06/22 Python
Python绘制组合图的示例
2020/09/18 Python
python基于爬虫+django,打造个性化API接口
2021/01/21 Python
HTML5标签与HTML4标签的区别示例介绍
2013/07/18 HTML / CSS
中国电子产品外贸网站:MiniIntheBox
2017/02/06 全球购物
斯巴达比赛商店:Spartan Race
2019/01/08 全球购物
工作自荐信
2013/12/11 职场文书
博士毕业生自我鉴定范文
2014/04/13 职场文书
交通安全标语
2014/06/06 职场文书
毕业生找工作自荐书
2014/06/30 职场文书
2014第二批党的群众路线教育实践活动对照检查材料思想汇报
2014/09/18 职场文书
二手车交易协议书标准版
2014/11/16 职场文书
2015年元旦主持词开场白
2014/12/14 职场文书
神农溪导游词
2015/02/11 职场文书
解决golang在import自己的包报错的问题
2021/04/29 Golang
使用Navicat Premium工具将oracle数据库迁移到MySQL
2021/05/27 Oracle
全网非常详细的pytest配置文件
2022/07/15 Python