4.Knockout.Js(事件绑定)

前言javascript

click绑定在DOM元素上添加事件句柄以便元素被点击的时候执行定义的JavaScript 函数。大部分是用在button,input和链接a上,可是能够在任意元素上使用。html

简单示例java

复制代码
<h2>ClickBind</h2>
<div>
    You've clicked <span data-bind="text: numberOfClicks"></span> times <button data-bind="click: incrementClickCounter">Click me</button> </div> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { numberOfClicks: ko.observable(0), incrementClickCounter: function() { var previousCount = this.numberOfClicks(); this.numberOfClicks(previousCount + 1); } }; ko.applyBindings(viewModel); </script>
复制代码

预览效果数组

  

每次点击按钮的时候,都会调用incrementClickCounter()函数,而后更新自动更新点击次数。浏览器

你能够声明任何JavaScript函数 – 不必定非要是view model里的函数。你能够声明任意对象上的任何函数,例如: someObject.someFunction。服务器

View model上的函数在用的时候有一点点特殊,就是不须要引用对象的,直接引用函数自己就好了,好比直接写incrementClickCounter 就能够了,而无需写成: viewModel.incrementClickCounter(尽管是合法的)。app

传参数给你的click 句柄异步

 最简单的办法是传一个function包装的匿名函数:函数

<button data-bind="click: function() { viewModel.myFunction('param1', 'param2') }"> Click me </button>

这样,KO就会调用这个匿名函数,里面会执行viewModel.myFunction(),而且传进了'param1' 和'param2'参数。post

访问事件源对象

 有些状况,你可能须要使用事件源对象,Knockout会将这个对象传递到你函数的第一个参数:

复制代码
<button data-bind="click: myFunction"> Click me event </button> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { numberOfClicks: ko.observable(0), incrementClickCounter: function() { var previousCount = this.numberOfClicks(); this.numberOfClicks(previousCount + 1); }, myFunction: function (event) { //////  } }; ko.applyBindings(viewModel); </script>
复制代码

若是你须要的话,可使用匿名函数的第一个参数传进去,而后在里面调用:

<button data-bind="click: function(event) { viewModel.myFunction(event, 'param1', 'param2') }"> Click me </button>

这样,KO就会将事件源对象传递给你的函数而且使用了。

容许执行默认事件

默认状况下,Knockout会阻止冒泡,防止默认的事件继续执行。例如,若是你点击一个a链接,在执行完自定义事件时它不会链接到href地址。这特别有用是由于你的自定义事件主要就是操做你的view model,而不是链接到另一个页面。

固然,若是你想让默认的事件继续执行,你能够在你click的自定义函数里返回true。

防止事件冒泡

默认状况下,Knockout容许click事件继续在更高一层的事件句柄上冒泡执行。例如,若是你的元素和父元素都绑定了click事件,那当你点击该元素的时候两个事件都会触发的。若是须要,你能够经过额外的绑定clickBubble来禁止冒泡。例如:

<div data-bind="click: myDivHandler"> <button data-bind="click: myButtonHandler, clickBubble: false"> Click me </button> </div>

默认状况下,myButtonHandler会先执行,而后会冒泡执行myDivHandler。但一旦你设置了clickBubble为false的时候,冒泡事件会被禁止

Knockout.Js官网学习(event绑定、submit绑定)

event绑定

event绑定在DOM元素上添加指定的事件句柄以便元素被触发的时候执行定义的JavaScript 函数。大部分状况下是用在keypress,mouseover和mouseout上。

简单示例

 

复制代码
<div>
    <div data-bind="event: { mouseover: enableDetails, mouseout: disableDetails }"> Mouse over me </div> <div data-bind="visible: detailsEnabled"> Details </div> </div> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { detailsEnabled: ko.observable(false), enableDetails:function() { this.detailsEnabled(true); }, disableDetails:function () { this.detailsEnabled(false); } }; ko.applyBindings(viewModel); </script>
复制代码

就是经过在一个div上绑定两个事件,一个鼠标点上去的mouseover让下面的div内容显示出来,另外一个是鼠标移出mouseout让下面的div内容再隐藏。

你能够声明任何JavaScript函数 – 不必定非要是view model里的函数。你能够声明任意对象上的任何函数,例如: event: { mouseover: someObject.someFunction }。

View model上的函数在用的时候有一点点特殊,就是不须要引用对象的,直接引用函数自己就好了,好比直接写event: { mouseover: enableDetails } 就能够了,而无需写成: event: { mouseover: viewModel.enableDetails }(尽管是合法的)。

submit绑定

 submit绑定在form表单上添加指定的事件句柄以便该form被提交的时候执行定义的JavaScript 函数。只能用在表单form元素上。

 

 当你使用submit绑定的时候, Knockout会阻止form表单默认的submit动做。换句话说,浏览器会执行你定义的绑定函数而不会提交这个form表单到服务器上。能够很好地 解释这个,使用  submit绑定就是为了处理view model的自定义函数的,而不是再使用普通的HTML form表单。若是你要继续执行默认的HTML form表单操做,你能够在你的submit句柄里返回true。

submit简单示例

<form data-bind="submit: doSomething"> ... form contents go here ... <input type="text" value="1" id="test"/> <button type="submit">Submit</button> </form>

简单的UI元素

        doSomething: function (formElement) {
            alert(formElement[0].outerHTML); }

简单的viewModel属性

总共有两个元素一个是录入框,另外一个是submit提交按钮

在form上,你可使用click绑定代替submit绑定。不过submit能够handle其它的submit行为,好比在输入框里输入回车的时候能够提交表单。

Knockout.Js官网学习(enable绑定、disable绑定)

enable绑定

enable绑定使DOM元素只有在参数值为 true的时候才enabled。在form表单元素input,select,和textarea上很是有用。

enable简单示例

 

复制代码
<h2>enableBind</h2>
<p>    <input type='checkbox' data-bind="checked: hasCellphone"/> I have a cellphone</p> <p> Your cellphone number: <input type='text' data-bind="value: cellphoneNumber, enable: hasCellphone"/></p> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { hasCellphone: ko.observable(false), cellphoneNumber:ko.observable("") }; ko.applyBindings(viewModel); </script>
复制代码

这个例子里,“Your cellphone number”后的text box 初始状况下是禁用的,只有当用户点击标签 “I have a cellphone”的时候才可用。

声明DOM元素是否可用enabled。

非布尔值会被解析成布尔值。例如0和null被解析成false,21和非null对象被解析给true。

若是你的参数是observable的,那绑定会随着observable值的改变而自动更新enabled/disabled状态。若是不是,则只会设置一次而且之后再也不更新。

任意使用JavaScript表达式

 不牢牢限制于变量 – 你可使用任何JavaScript表达式来控制元素是否可用。例如

<button data-bind="enable: parseAreaCode(viewModel.cellphoneNumber()) != '555'"> 
  Do something
</button>

disable绑定

disable绑定使DOM元素只有在参数值为 true的时候才disabled。在form表单元素input,select,和textarea上很是有用。

disable绑定和enable绑定正好相反,详情请参考enable绑定

Knockout.Js官网学习(value绑定)

前言

value绑定是关联DOM元素的值到view model的属性上。主要是用在表单控件<input>,<select>和<textarea>上。

当用户编辑表单控件的时候, view model对应的属性值会自动更新。一样,当你更新view model属性的时候,相对应的元素值在页面上也会自动更新。

注:若是你在checkbox或者radio button上使用checked绑定来读取或者写入元素的 checked状态,而不是value 值的绑定。

简单示例

 代码以下对两个input进行value的属性绑定

复制代码
<p>Login name: <input data-bind="value: userName"/></p> <p>Password: <input type="password" data-bind="value: userPassword"/></p> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { userName: ko.observable(""), userPassword: ko.observable("abc") }; ko.applyBindings(viewModel); </script> 
复制代码

运行后效果为

注意密码的type为password

KO设置此参数为元素的value值。以前的值将被覆盖。

    若是参数是监控属性observable的,那元素的value值将根据参数值的变化而更新,若是不是,那元素的value值将只设置一次而且之后不在更新。

    若是你提供的参数不是一个数字或者字符串(而是对象或者数组)的话,那显示的value值就是yourParameter.toString() 的内容(一般没用,因此最好都设置为数字或者字符串)。

    无论何时,只要你更新了元素的值,那 KO都会将view model对应的属性值自动更新。默认状况下当用户离开焦点(例如onchange事件)的时候,KO才更新这个值,可是你能够经过第2个参数valueUpdate来特别指定改变值的时机。

valueUpdate

  若是你使用valueUpdate参数,那就是意味着KO将使用自定义的事件而不是默认的离开焦点事件。下面是一些最经常使用的选项:

            “change”(默认值) - 当失去焦点的时候更新view model的值,或者是<select> 元素被选择的时候。

            “keyup” – 当用户敲完一个字符之后当即更新view model。

            “keypress” – 当用户正在敲一个字符但没有释放键盘的时候就当即更新view model。不像 keyup,这个更新和keydown是同样的。

            “afterkeydown” – 当用户开始输入字符的时候就更新view model。主要是捕获浏览器的keydown事件或异步handle事件。

        上述这些选项,若是你想让你的view model进行实时更新,使用“afterkeydown”是最好的选择。

<p>Your value: <input data-bind="value: someValue, valueUpdate: 'afterkeydown'"/></p> <p>You have typed: <span data-bind="text: someValue"></span></p>
someValue: ko.observable("edit me")

绑定下拉菜单drop-down list(例如SELECT)

 Knockout对下拉菜单drop-down list绑定有一个特殊的支持,那就是在读取和写入绑定的时候,这个值能够是任意JavaScript对象,而没必要非得是字符串。在你让你用户选择一组model对象的时候很是有用。具体例子,参考options绑定。

相似,若是你想建立一个multi-select list,参考selectedOptions绑定。

更新observable和non-observable属性值

 若是你用value绑定将你的表单元素和你的observable属性关联起来,KO设置的2-way的双向绑定,任何一方改变都会更新另一方的值。

 可是,若是你的元素绑定的是一个non-observable属性(例如是一个原始的字符串或者JavaScript表达式) ,KO会这样执行:

  1.若是你绑定的non-observable属性是简单对象,例如一个常见的属性值,KO会设置这个值为form表单元素的初始值,若是你改 变form表单元素的值,KO会将值从新写回到view mode的这个属性。但当这个属性本身改变的时候,元素却不会再变化了(由于不是observable的),因此它仅仅是1-way绑定。

  2.若是你绑定的non-observable属性是复杂对象,例如复杂的JavaScript 表达式或者子属性,KO也会设置这个值为form表单元素的初始值,可是改变form表单元素的值的时候,KO不会再写会view model属性,这种状况叫one-time-only value setter,不是真正的绑定。

例如:

复制代码
<p>First value: <input data-bind="value: firstValue"/></p> <!-- two-way binding --> <p>Second value: <input data-bind="value: secondValue"/></p> <!-- one-way binding --> <p>Third value: <input data-bind="value: secondValue.length"/></p> <!-- no binding --> <script type="text/javascript"> var viewModel = { firstValue: ko.observable("hello"), // Observable secondValue: "hello, again"// Not observable  }; ko.applyBindings(viewModel); </script>
复制代码

 Knockout.Js官网学习(checked 绑定)

前言

checked绑定是关联到checkable的form表单控件到view model上 - 例如checkbox(<input type='checkbox'>)或者radio button(<input type='radio'>) 。当用户check关联的form表单控件的时候,view model对应的值也会自动更新,相反,若是view model的值改变了,那控件元素的check/uncheck状态也会跟着改变。

注:对text box,drop-down list和全部non-checkable的form表单控件,用value绑定来读取和写入是该元素的值,而不是checked绑定。

简单示例

 示例代码

复制代码
<p>Send me spam:<input type="checkbox" data-bind="checked:wantsSpam" /></p> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { wantsSpam:ko.observable(true) }; viewModel.wantsSpam(false); ko.applyBindings(viewModel); </script>
复制代码

运行以后

 对于checkbox,当参数为true的时候,KO会设置元素的状态为checked,反正设置为unchecked。若是你传的参数不是布尔值,那KO将会解析成布尔值。也就是说非0值和非null对象,非空字符串将被解析成true,其它值都被解析成false。

当用户check或者uncheck这个checkbox的时候,KO会将view model的属性值相应地设置为true或者false。

Checkbox关联到数组

复制代码
<p>Send me spam:<input type="checkbox" data-bind="checked:wantsSpam" /></p> <div data-bind="visible: wantsSpam"> Preferred flavors of spam: <div> <input type="checkbox" value="cherry" data-bind="checked: spamFlavors"/> Cherry </div> <div> <input type="checkbox" value="almond" data-bind="checked: spamFlavors"/> Almond </div> <div> <input type="checkbox" value="msg" data-bind="checked: spamFlavors"/> Monosodium Glutamate </div> </div> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { wantsSpam: ko.observable(true), spamFlavors: ko.observableArray(["cherry", "almond"]) }; ko.applyBindings(viewModel); viewModel.wantsSpam(false); viewModel.spamFlavors.push("msg"); </script
复制代码

添加radio button

    <div><input type="radio" name="flavorGroup" value="cherry" data-bind="checked: spamFlavor"/> Cherry</div> <div><input type="radio" name="flavorGroup" value="almond" data-bind="checked: spamFlavor"/> Almond</div> <div><input type="radio" name="flavorGroup" value="msg" data-bind="checked: spamFlavor"/> Monosodium Glutamate</div>

 

spamFlavor:ko.observable("cherry")

对于radio buttons,KO只有当参数值等于radio button value属性值的时候才设置元素为checked状态。因此参数应是字符串。在上面的例子里只有当view model 的spamFlavor 属性等于“almond”的时候,该radio button才会设置为checked。

固然,最有用的是设置一组radio button元素对应到一个单个的view model 属性。确保一次只能选择一个radio button须要将他们的name属性名都设置成同样的值(例如上个例子的flavorGroup值)。这样的话,一次就只能选择一个了。

若是参数是监控属性observable的,那元素的checked状态将根据参数值的变化而更新,若是不是,那元素的value值将只设置一次而且之后不在更新

Knockout.Js官网学习(options绑定)

前言

options绑定控制什么样的options在drop-down列表里(例如:<select>)或者 multi-select 列表里 (例如:<select size='6'>)显示。此绑定不能用于<select>以外的元素。关联的数据应是数组(或者是observable数组),& lt;select>会遍历显示数组里的全部的项。

对于multi-select列表,设置或者获取选择的多项须要使用selectedOptions绑定。对于single-select列表,你也可使用value绑定读取或者设置元素的selected项。

Drop-down list

 

复制代码
<p>Destination country: <select data-bind="options: availableCountries"></select></p> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { availableCountries: ko.observableArray(['France', 'Germany', 'Spain']) }; ko.applyBindings(viewModel); viewModel.availableCountries.push('China'); </script>
复制代码

 

该参数是一个数组(或者observable数组)。对每一个item,KO都会将它做为一个<option> 添加到<select>里,以前的options都将被删除。

若是参数是一个string数组,那你不须要再声明任何其它参数。<select>元素会将每一个string显示为一个option。 不过,若是你让用户选择的是一个JavaScript对象数组(不只仅是string),那就须要设置optionsText和optionsValue 这两个参数了。

若是参数是监控属性observable的,那元素的options项将根据参数值的变化而更新,若是不是,那元素的value值将只设置一次而且之后不在更新。

 

若是对上面的select UI元素加上multiple="true"

<select data-bind="options: availableCountries" multiple="true"></select>

这能够说是Multi-select list

Drop-down list展现的任意JavaScript对象,不只仅是字符串

 

复制代码
<p>Destination country: <select data-bind="options: availableCountries" multiple="true"></select></p> <p> Your country: <select data-bind="options: Countries,optionsText: 'countryName', value: selectedCountry, optionsCaption: 'Choose...'"> </select> </p> <div data-bind="visible: selectedCountry"> You have chosen a country with population <span data-bind="text: selectedCountry() ? selectedCountry().countryPopulation : 'unknown'"></span>. </div> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var Country = function (name, population) { this.countryName = name; this.countryPopulation = population; }; var viewModel = { availableCountries: ko.observableArray(['France', 'Germany', 'Spain']), selectedCountry: ko.observable(), Countries: ko.observableArray([ new Country("UK", 65000000), new Country("USA", 320000000), new Country("Sweden", 29000000) ]) }; ko.applyBindings(viewModel); viewModel.availableCountries.push('China'); </script>
复制代码

optionsCaption

有时候,默认状况下不想选择任何option项。可是single-select drop-down列表因为每次都要默认选择以项目,怎么避免这个问题呢?经常使用的方案是加一个“请选择的”或者“Select an item”的提示语,或者其它相似的,而后让这个项做为默认选项。

咱们使用optionsCaption参数就能很容易实现,它的值是字符串型,做为默认项显示。例如:

<select data-bind='options: myOptions, optionsCaption: "Select an item...", value: myChosenValue'></select>

KO会在全部选项上加上这一个项,而且设置value值为undefined。因此,若是myChosenValue被设置为undefined(默认是observable的),那么上述的第一个项就会被选中

Drop-down list展现的任意JavaScript对象,显示text是function的返回值

<select data-bind="options: Countries, optionsText: function(item) { return item.countryName + ' (pop: ' + item.countryPopulation + ')' }, value: selectedCountry, optionsCaption: 'Choose...'"> </select>

optionsText

上面《Drop-down list展现的任意JavaScript对象,不只仅是字符串》中展现的绑定 JavaScript对象到option上 – 不只仅是字符串。这时候你须要设置这个对象的那个属性做为drop-down列表或multi-select列表的text来显示。设置额外的参数 optionsText将对象的属性名countryName做为显示的文本。

若是不想仅仅显示对象的属性值做为每一个item项的text值,那你能够设置optionsText 为JavaScript 函数,而后再函数里经过本身的逻辑返回相应的值(该函数参数为item项自己)。

optionsValue

和optionsText相似, 你也能够经过额外参数optionsValue来声明对象的那个属性值做为该<option>的value值。

经典场景:如在更新options的时候想保留原来的已经选择的项。例如,当你重复屡次调用Ajax获取car列表的时候,你要确保已经选择的某个 car一直都是被选择上,那你就须要设置optionsValue为“carId”或者其它的unique标示符,不然的话KO找不知道以前选择的car 是新options里的哪一项

selectedOptions

对于multi-select列表,你能够用selectedOptions读取和设置多个选择项。技术上看它是一个单独的绑定,有本身的文档,请参考: selectedOptions绑定。

Knockout.Js官网学习(selectedOptions绑定、uniqueName 绑定)

selectedOptions绑定

selectedOptions绑定用于控制multi-select列表已经被选择的元素,用在使用options绑定的<select>元素上。

当用户在multi-select列表选择或反选一个项的时候,会将view model的数组进行相应的添加或者删除。一样,若是view model上的这个数组是observable数组的话,你添加或者删除任何item(经过push或者splice)的时候,相应的UI界面里的 option项也会被选择上或者反选。这种方式是2-way绑定。

注:控制single-select下拉菜单选择项,你可使用value绑定。

示例代码

复制代码
<p>    Choose some countries you'd like to visit: <select data-bind="options: availableCountries, selectedOptions: chosenCountries" size="5" multiple="true"> </select> </p> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { availableCountries: ko.observableArray(['France', 'Germany', 'Spain']), chosenCountries: ko.observableArray(['Germany']) }; ko.applyBindings(viewModel); viewModel.chosenCountries.push('France'); </script>
复制代码

该参数是数组(或observable数组)。KO设置元素的已选项为和数组里match的项,以前的已选择项将被覆盖。

若是参数是依赖监控属性observable数组,那元素的已选择项selected options项将根据参数值的变化(经过push,pop,或其它observable数组方法)而更新,若是不是,那元素的已选择项selected options将只设置一次而且之后不在更新。

无论该参数是否是observable数组,用户在multi-select列表里选择或者反选的时候,KO都会探测到,而且更新数组里的对象以达到同步的结果。这样你就能够获取options已选项。

支持让用户选择任意JavaScript对象

在上面的例子里,用户能够选择数组里的字符串值,可是选择不限于字符串,若是你愿意你能够声明包含任意JavaScript对象的数组,查看options绑定如何显示JavaScript对象到列表里。

这种场景,你能够用selectedOptions来读取或设置这些对象自己,而不是页面上显示的option表示形式,这样作在大部分状况下都非 常清晰。view model就能够探测到你从数组对象里选择的项了,而没必要关注每一个项和页面上展现的option项是如何map的。

uniqueName绑定

 uniqueName绑定确保所绑定的元素有一个非空的name属性。若是该元素没有name属性,那绑定会给它设置一个unique的字符串值做为name属性。你不会常常用到它,只有在某些特殊的场景下才用到。

  1.在使用KO的时候,一些技术可能依赖于某些元素的name属性,尽快他们没有什么意义。例如,jQuery Validation验证当前只验证有name属性的元素。为配合Knockout UI使用,有些时候须要使用uniqueName绑定避免让jQuery Validation验证出错。

  2.IE 6下,若是radio button没有name属性是不容许被checked了。大部分时候都没问题,由于大部分时候radio button元素都会有name属性的做为一组互相的group。不过,若是你没声明,KO内部会在这些元素上使用uniqueName那么以确保他们可 以被checked。

 例如:

<input data-bind="value: someModelProperty, uniqueName: true"/>

 就像上面的例子同样,传入true(或者能够转成true的值)以启用uniqueName绑定。

相关文章
相关标签/搜索