您好,欢迎来到纷纭教育。
搜索
您的当前位置:首页javascript MVC框架Knockout简介

javascript MVC框架Knockout简介

来源:纷纭教育
Knockout简介

Introduction

Knockout是围绕以下三个核心功能是建立起来的:

1. 监控属性(Observables)和依赖跟踪(Dependency tracking) 2. 声明式绑定(Declarative bindings) 3. 模板(Templating)

创建一个view model,只需要声明任意的JavaScript object。例如:

var myViewModel = { personName: 'Bob', personAge: 123 };

你可以为view model创建一个声明式绑定的简单view。例如:下面的代码显示personName 值:

The name is

激活Knockout

激活Knockout,需要添加如下的

参数 主参数

当参数设置为一个假值时(例如:布尔值false,数字值0,或者null,或者undefined) ,该绑定将设置该元素的style.display值为none,让元素隐藏。它的优先级高于你在CSS里定义的任何display样式。

当参数设置为一个真值时(例如:布尔值true,或者非空non-null的对象或者数组) ,该绑定会删除该元素的style.display值,让元素可见。然后你在CSS里自定义的display样式将会自动生效。 如果参数是监控属性observable的,那元素的visible状态将根据参数值的变化而变化,如果不是,那元素的visible状态将只设置一次并且以后不在更新。 其它参数 无

注:使用函数或者表达式来控制元素的可见性

你也可以使用JavaScript函数或者表达式作为参数。这样的话,函数或者表达式的结果将决定是否显示/隐藏这个元素。例如:

0\">

You will see this message only when 'myValues' has at least one member.

依赖性

除KO核心类库外,无依赖。

text 绑定

目的

text 绑定到DOM元素上,使得该元素显示的文本值为你绑定的参数。该绑定在显示或者上非常有用,但是你可以用在任何元素上。 例子

Today's message is:

参数

主参数

KO将参数值会设置在元素的innerText (IE)或textContent(Firefox和其它相似浏览器)属性上。原来的文本将会被覆盖。

如果参数是监控属性observable的,那元素的text文本将根据参数值的变化而更新,如果不是,那元素的text文本将只设置一次并且以后不在更新。

如果你传的是不是数字或者字符串(例如一个对象或者数组),那显示的文本将是yourParameter.toString()的等价内容。 其它参数 无

注1:使用函数或者表达式来决定text值

如果你想让你的text更可控,那选择是创建一个依赖监控属性(dependent observable),然后在它的执行函数里编码,决定应该显示什么样的text文本。 例如:

The item is today.

现在,text文本将在―expensive‖和―affordable‖之间替换,取决于价格怎么改变。

然而,如果有类似需求的话其实没有必要再声明一个依赖监控属性(dependent observable),你只需要按照如下代码写JavaScript表达式就可以了:

The item is 50 ? 'expensive' : 'affordable'\"> today.

结果是一样的,但我们不需要再声明依赖监控属性(dependent observable)。

注2:关于HTML encoding

因为该绑定是设置元素的innerText或textContent (而不是innerHTML),所以它是安全的,没有HTML或者脚本注入的风险。例如:如果你编写如下代码:

viewModel.myMessage(\"Hello, world!\");

… 它不会显示斜体字,而是原样输出标签。如果你需要显示HTML内容,请参考html绑定.

注3:关于IE 6的白空格whitespace

IE6有个奇怪的问题,如果 span里有空格的话,它将自动变成一个空的span。如果你想编写如下的代码的话,那Knockout将不起任何作用:

Welcome, to our web site.

… IE6 将不会显示span中间的那个空格,你可以通过下面这样的代码避免这个问题:

Welcome,   to our web site.

IE6以后版本和其它浏览器都没有这个问题 依赖性

除KO核心类库外,无依赖。

html 绑定

目的

html绑定到DOM元素上,使得该元素显示的HTML值为你绑定的参数。如果在你的view model里声明HTML标记并且render的话,那非常有用。 例子

参数 主参数

KO设置该参数值到元素的innerHTML属性上,元素之前的内容将被覆盖。

如果参数是监控属性observable的,那元素的内容将根据参数值的变化而更新,如果不是,那元素的内容将只设置一次并且以后不在更新。

如果你传的是不是数字或者字符串(例如一个对象或者数组),那显示的文本将是yourParameter.toString()的等价内容。 其它参数 无

注:关于HTML encoding

因为该绑定设置元素的innerHTML,你应该注意不要使用不安全的HTML代码,因为有可能引起脚本注入攻击。如果你不确信是否安全(比如显示用户输入的内容),那你应该使用text绑定,因为这个绑定只是设置元素的text 值innerText和textContent。 依赖性

除KO核心类库外,无依赖。

css 绑定

目的

css绑定是添加或删除一个或多个CSS class到DOM元素上。非常有用,比如当数字变成负数时高亮显示。(注:如果你不想应用CSS class而是想引用style属性的话,请参考style绑定。) 例子

Profit Information

效果就是当currentProfit 小于0的时候,添加profitWarning CSS class到元素上,如果大于0则删除这个CSS class。 参数 主参数

该参数是一个JavaScript对象,属性是你的CSS class名称,值是比较用的true或false,用来决定是否应该使用这个CSS class。

你可以一次设置多个CSS class。例如,如果你的view model有一个叫isServre的属性,

非布尔值会被解析成布尔值。例如, 0和null被解析成false,21和非null对象被解析成true。 如果参数是监控属性observable的,那随着值的变化将会自动添加或者删除该元素上的CSS class。如果不是,那CSS class将会只添加或者删除一次并且以后不在更新。

你可以使用任何JavaScript表达式或函数作为参数。KO将用它的执行结果来决定是否应用或删除CSS class。 其它参数 无

注:应用的CSS class的名字不是合法的JavaScript变量命名 如果你想使用my-class class,你不能写成这样:

...

… 因为my-class不是一个合法的命名。解决方案是:在my-class两边加引号作为一个字符串使用。这是一个合法的JavaScript 对象文字(从JSON技术规格说明来说,你任何时候都应该这样使用,虽然不是必须的)。例如,

...

依赖性

除KO核心类库外,无依赖。

style 绑定

目的

style绑定是添加或删除一个或多个DOM元素上的style值。比如当数字变成负数时高亮显示,或者根据数字显示对应宽度的Bar。(注:如果你不是应用style值而是应用CSS class的话,请参考CSS绑定。) 例子

Profit Information

当currentProfit 小于0的时候div的style.color是红色,大于的话是黑色。 参数 主参数

该参数是一个JavaScript对象,属性是你的style的名称,值是该style需要应用的值。 你可以一次设置多个style值。例如,如果你的view model有一个叫isServre的属性,

...

如果参数是监控属性observable的,那随着值的变化将会自动添加或者删除该元素上的style值。如果不是,那style值将会只应用一次并且以后不在更新。

你可以使用任何JavaScript表达式或函数作为参数。KO将用它的执行结果来决定是否应用或删除style值。

其它参数 无

注:应用的style的名字不是合法的JavaScript变量命名

如果你需要应用font-weight或者text-decoration,你不能直接使用,而是要使用style对应的JavaScript名称。

错误:{ font-weight: someValue }; 正确:{ fontWeight: someValue } 错误:{ text-decoration: someValue }; 正确:{ textDecoration: someValue } 参考:style名称和对应的JavaScript 名称列表。 依赖性

除KO核心类库外,无依赖。

attr 绑定

目的

attr 绑定提供了一种方式可以设置DOM元素的任何属性值。你可以设置img的src属性,连接的href属性。使用绑定,当模型属性改变的时候,它会自动更新。 例子

Report

呈现结果是该连接的href属性被设置为year-end.html, title属性被设置为Report including final year-end statistics。

参数 主参数

该参数是一个JavaScript对象,属性是你的attribute名称,值是该attribute需要应用的值。 如果参数是监控属性observable的,那随着值的变化将会自动添加或者删除该元素上的attribute值。如果不是,那attribute值将会只应用一次并且以后不在更新。 其它参数 无

注:应用的属性名字不是合法的JavaScript变量命名

如果你要用的属性名称是data-something的话,你不能这样写:

...

… 因为data-something 不是一个合法的命名。解决方案是:在data-something两边加引号作为一个字符串使用。这是一个合法的JavaScript 对象文字(从JSON技术规格说明来说,你任何时候都应该这样使用,虽然不是必须的)。例如,

...

依赖性

除KO核心类库外,无依赖。

控制流程绑定

foreach绑定 目标

foreach绑定在一个array中循环,并对每一个array的元素复制产生一段给出的html标记,并对产生的标记设置绑定关系。这在render一个list或table的时候特别有用。

假设你的array是一个observable array,每当增加、删除array中的元素的时候,绑定会快速的更新匹配的UI,插入或删除对应的标记文本,或重新排序DOM元素。 我们也可以任意嵌套任意数量的带有if和with的foreach绑定。

案例1:数组迭代

下面这个例子使用foreach遍历一个array产生一个只读的table的每个行。

First name

Last name

ko.applyBindings({ people: [{

firstName: 'Bert', lastName: 'Bertington' }, {

firstName: 'Charles', lastName: 'Charlesforth' }, {

firstName: 'Denise', lastName: 'Dentiste' }] });

案例2:增加/删除数组

下面这个例子中,如果数组是可监控的,UI会跟随数组的变化而同步变更。

View的代码:

People

  • Name at position :

    Remove

  • Add

    View model的代码:

    function AppViewModel() { var self = this;

    self.people = ko.observableArray([{ name: 'Bert' }, {

    name: 'Charles' }, {

    name: 'Denise'

    }]);

    self.addPerson = function () { self.people.push({

    name: \"New at \" + new Date() }); };

    self.removePerson = function () { self.people.remove(this); } }

    ko.applyBindings(new AppViewModel());

    参数

    主要参数

    传递需要迭代的数组的名字,binding的结果是为每一个数组元素产生一个html片段。 另外一种方式是传递一个javascript对象,带有data属性,里面是你希望迭代的数组,这个javascript还可以有其他属性,象afterAdd 和 includeDestroyed。参考下面的例子。 如果提供的数组是可监控的,那么foreach会根据数组的变更来同步产生对应的DOM片段。

    其他参数

    说明1:使用$data 引用每一个数组的成员

    在foreach的块中,可以绑定数组成员的属性,像例子1中的firstName和lastName。

    但是如何引用数组元素的自身呢?可以使用特殊的上下文属性$data,在foreach块中,它表示当前的项目。 例子:

  • The current item is:

  • ko.applyBindings({

    months: ['Jan', 'Feb', 'Mar', 'etc'] });

    如果你愿意,你可以在每个引用的属性前加上$data,比如:

    说明2:使用$index, $parent等其他上下文属性(context properties)

    $index是当前迭代数组的0开始的下标,$index本身也是一个可监控的值,会因为数组的变化而改变。

    $parent相似,引用foreach外部的数据对象($data)。比如:

  • likes the blog post

  • 说明3:使用“as” 提供“foreach”项目的别名

    如在说明1中描述的那样,你可以使用$data上下文变量来引用当前的数组元素。在一些情况下,也许要给当前的元素指定别名,如:

    现在,在foreach块中的任何地方使用person都能访问当前的数组元素。这在有foreach嵌套的情况下非常有用。例如:

  • :

  • 注:记住as后面是字符串值(例如as: 'category',而不是as: category)。

    说明4:在没有容器的情况下使用foreach

    某些情况下,需要在没有任何父容器element的情况下输出做foreach的binding。例如,要输出下面的标记内容:

      Header item

    • Item A
    • Item B
    • Item C

    在这种情况下没有地方写foreach的binding。这种情况下需要用的缺少容器的foreach语法,例如:

      Header item

    • Item

    ko.applyBindings({ myItems: ['A', 'B', 'C'] });

    注释被当成一个虚拟的容器的开始和结束的标记,在虚拟容器中的标记文本被作为foreach块的内容。

    说明5:如何检测和获取数组的变化

    如果变更model的数组的内容(增加、移动、或删除里面的项目),foreach binding使用有效率的差异变更算法,指出那些数据发生了变化,这样就可以更新匹配的DOM。这意味着可以获取任意组合的并发变更。

      

    当增加(add)数组成员,foreach会render新的DOM片段,并合并到已有的DOM之中 当删除(delete)数组成员,foreach会简单的删除对应的DOM元素

    当重新排序(reorder)数组成员(保持相同的数组成员实例),foreach会将对应的DOM移动到新的位置

    注意:改变重新排序(reorder)不保证:算法能快速的结束,它被设计和优化用于检测简单数组元素的

    少量的位置改变。如果算法检测到太多的并发变更,并伴随着无关的插入和删除,处于速度的考虑会将move替换成delete+add的操作。在这种情况下对应的DOM元素会被从DOM树上摘除,并重新创建。多数开发者不会碰到这种情况,如果不幸碰到了,最终用户的体验也会是一致的。

    说明6:默认销毁(Destroyed)的数组元素是隐藏的(hidden)

    有事也许需要删除数组中的元素,但是并不想丢失记录的内容。这中情况被称为非破坏性的删除(non-destructive delete)。操作细节可以参考the destroy function on observableArray.

    默认情况下,foreach binding会跳过标记为销毁的数组元素,如果你需要显示这些以及销毁的元素,可以使用includeDestroyed选项。例如:

    ...

    说明7:后处理或设置产生的DOM元素的动画效果

    如果需要在产生的DOM上运行更多自定义的逻辑,可以使用下面描述的任意的afterRender/afterAdd/beforeRemove/beforeMove/afterMove callbacks。

    注意:这些callbacks仅仅是用于触发一个list被改变时的动画效效果。如果你的目标是向新的DOM元素上附加其它的行为(例如,事件挂接,或激活第三方的控件),处理这些行为应该使用custom binding实现,这样你可以在任何地方实现这些行为,而不是依赖foreach binding。

    下面是一个使用afterAdd向新添加的项目上添加” yellow fade”效果的例子,使用jQuery的Color plugin来设置背景颜色的动画效果。

    Add ko.applyBindings({

    myItems: ko.observableArray(['A', 'B', 'C']), yellowFadeIn: function (element, index, data) { $(element).filter(\"li\")

    .animate({ backgroundColor: 'yellow' }, 200) .animate({ backgroundColor: 'white' }, 800); },

    addItem: function () { this.myItems.push('New item'); } });

    详细说明: 

    afterRender— 在foreach容器内的标记块被复制并插入到文档树中的时候被调用,foreach初始化完毕数

    组的时候也会调用。Knockout会传递以下参数到callback:

    1. 插入的DOM元素的数组 2. 参与绑定的data item

    afterAdd — 与afterRender相似,除了它只在新元素被添加到关联的数组中(不包括foreach初始化的那次)的时候被调用。一般在afterAdd中调用像jQuery的$(domNode).fadeIn()这样的代码,可以添加数组元

    素添加之后的转换效果。Knockout会传递以下参数到callback:

    1. 新添加的DOM

    2. 新添加的元素的数组内的索引 3. 新添加的数组的元素

    beforeRemove — 当数组中的元素被删除的时候调用,调用时对应的DOM节点还未从DOM树上删除。如果指定了beforeRemove callback, 删除对应的DOM节点就会成为你的责任。一个显而易见的使用方式是执行一

    些箱jQuery的$(domNode).fadeOut()一样的代码来增加DOM删除的特效,这种情况下Knockout是无法知道DOM节点被删除的确切的时间点的,所以需要你来完成删除的操作。Knockout会传递以下参数到callback:

    1. 将被删除的DOM节点

    2. 被删除的数组元素在数组中的索引 3. 被删除的数组元素

     beforeMove — 在一个数组的成员改变位置的时候调用,此时对应的DOM还没有被调整。注意,beforeMove

    会在任何数组的元素的位置改变后被执行,因此如果在一个数组的中间插入一个元素,这会使后面所有的数组元素接收到位置改变的通知,因为每个数组的位置都会+1。你可以在beforeMove中获取被移动的DOM的原来的位置,然后在afterMove callback中添加移动DOM的效果。Knockout会传递以下参数到callback:

    1. 被移动的DOM节点 2. 被移动的数组元素的索引 3. 被移动的数组的元素

    afterMove — 在一个数组的成员已经改变了位置,并且foreach以及更新了DOM树的时候调用。注意,afterMove会在任何数组的元素的位置改变后被执行,因此如果在一个数组的中间插入一个元素,这会使

    后面所有的数组元素接收到位置改变的通知,因为每个数组的位置都会+1。Knockout会传递以下参数到callback:

    1. 被移动的DOM节点 2. 被移动的数组元素的索引 3. 被移动的数组的元素

    afterAdd和beforeRemove的例子,请参考animated transitions

    依赖

    无,仅Knockout核心库

    If绑定 目标

    If绑定的目标是使一个表达式的值为true的标记段出现在document之中(具有data-bind属性)。 If绑定使用与visible绑定相似的规则。不同的地方是在visible绑定中对应的标记片段会保留在DOM之中,仅仅是通过CSS开启、关闭DOM节点的可见性;而If绑定会将对应的标记的片段物理上向DOM添加或删除。

    例1

    这个例子演示如何根据一个可监控的值来增加或删除一个标记的片段。

    View的代码:

    Here is a message. Astonishing.

    ViewModel的代码:

    ko.applyBindings({

    displayMessage: ko.observable(false) });

    例2

    这个例子中,根据capital的值来决定是否输出标记片段。因为Mercury的capital的值是null,所以它没有输出标记片段。而Earth有非空的capital值,所有会输出标记片段。

  • Planet:

    Capital:

  • 参数

    主要参数

    希望求值的表达式。如果结果是true(或可以认为是true的值),对应的标记片段就会document中存在,并且其包含的data-bind属性会继续应用。如果结果是false,对应的标记片段就不会document中存在。

    如果表达式是任何可监控的值,那么当值发送变化的时候if块对应的标记片段会被动态的添加、删除。而在添加标记块之后,其包含的data-bind的属性会在新的标记块上应用。

    其他参数

    说明:没有容器的情况下使用if绑定

    有时希望在没有对应容器的情况下使用if绑定,可以参考下面的例子:

    • This item always appears
    • I want to make this item present/absent dynamically

    注释被当成一个虚拟的容器的开始和结束的标记,在虚拟容器中的标记文本被作为if块的内容。

    依赖

    无,仅Knockout核心库

    Ifnot绑定 目标

    Ifnot绑定与if绑定等价,差别仅仅是反转传递过来的表达式的值。

    说明:ifnot与反过来的if相同

    下面的标记:

    ...
    与下面的标记等价:

    ...

    假设someProperty是可监控的值。使用ifnot的原因仅仅是口味上的差别:一些开发者感觉ifnot更整洁。

    with绑定 目标

    with绑定创建一个新的绑定的上下文(binding context),因此其内部的元素的绑定会使用指定的上下文来执行绑定。

    当然,你可以在其他的流程控制绑定(if、foreach)中任意的嵌套使用with绑定。

    例1

    这是一个非常基本的绑定上下文切换的例子。

    Latitude: , Longitude:

    ko.applyBindings({ city: \"London\", coords: {

    latitude: 51.5001524, longitude: -0.1262362

    } });

    例2

    下面的例子演示:

     with绑定根据关联的值是否是null/undefined动态的增加或删除内部的标记。

     如果需要访问父绑定上下文的数据或函数,可以使用special context properties such as $parent and

    root

    View的代码:

    Twitter account:

    Get tweets

    Recent tweets fetched at

    Clear tweets

    ViewModel的代码:

    function AppViewModel() { var self = this;

    self.Name = ko.observable('@StephenFry'); self.resultData = ko.observable(); // No initial value

    self.getTweets = function () {

    Api.getTweetsForUser(self.Name(), function (data) { self.resultData({

    retrievalDate: new Date(), topTweets: data.slice(0, 5) }); }); }

    self.clearResults = function () {

    self.resultData(undefined); } }

    ko.applyBindings(new AppViewModel());

    参数

    主要参数

    作为绑定上下文的对象。

    如果提供的表达式的值的计算结果是null或undefined,内部的元素不会执行绑定,对应的DOM会从document上删除。

    如果提供的表达式或值是一个可监控的值,如果表达式的值发生了变化,内部的DOM节点会被清除,然后会产生一个新的标记快加入到document,并使用新的上下文重新执行绑定。

    附加参数

    说明1:没有容器的情况下使用with绑定

    和其他流程控制的绑定if和foreach类似,可以在没有对应的容器元素的情况下使用with绑定。这在仅需要一个位置来引入with绑定的情况下非常有用。 例如:

    注释被当成一个虚拟的容器的开始和结束的标记,在虚拟容器中的标记文本被作为with块的内容。

    依赖

    无,仅Knockout核心库

    与form 的fields协同工作

    click 绑定

    目的

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

    You've clicked times

    每次点击按钮的时候,都会调用incrementClickCounter()函数,然后更新自动更新点击次数。 参数 主参数

    Click点击事件时所执行的函数。

    你可以声明任何JavaScript函数 – 不一定非要是view model里的函数。你可以声明任意对象上的任何函数,例如:someObject.someFunction。

    View model上的函数在用的时候有一点点特殊,就是不需要引用对象的,直接引用函数本身就行了,比如直接写incrementClickCounter就可以了,而无需写成:viewModel.incrementClickCounter(尽管是合法的)。 其它参数 无

    注1:传参数给你的click 句柄

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

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

    注2:访问事件源对象

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

    如果你需要的话,可以使用匿名函数的第一个参数传进去,然后在里面调用:

    这样,KO就会将事件源对象传递给你的函数并且使用了。 注3: 允许执行默认事件

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

    当然,如果你想让默认的事件继续执行,你可以在你click的自定义函数里返回true。 注4:控制this句柄

    初学者可以忽略这小节,因为大部分都用不着,高级用户可以参考如下内容:

    KO在调用你定义的函数时,会将view model传给this对象(也就是ko.applyBindings使用的view model)。主要是方便你在调用你在view model里定义的方法的时候可以很容易再调用view model里定义的其它属性。例如: this.someOtherViewModelProperty。 如果你想引用其它对象,我们有两种方式:

     

    你可以和注1里那样使用匿名函数,因为它支持任意JavaScript 对象。

    你也可以直接引用任何函数对象。你可以使用bind使callback函数设置this为任何你选择的对象。例如:

    如果你是C#或Java开发人员,你可以疑惑为什么我们还要用bind函数到一个对象想,特别是像调用someObject.someFunction。原因是在JavaScript里,函数自己不是类的一部分,他们在单独存在的对象,有可能多个对象都引用同样的someFunction函数,所以当这个函数被调用的时候它不知道谁调用的(设置this给谁)。在你bind之前运行时是不会知道的。KO默认情况下设置this对象是view model,但你可以用bind语法重定义它。

    在注1里使用匿名函数的时候没有具体的要求,因为JavaScript代码someObject.someFunction()就意味着调用someFunction,然后设置this到 someObject对象上。 注5:防止事件冒泡

    默认情况下,Knockout允许click事件继续在更高一层的事件句柄上冒泡执行。例如,如果你的元素和父元素都绑定了click事件,那当你点击该元素的时候两个事件都会触发的。如果需要,你可以通过额外的绑定clickBubble来禁止冒泡。例如:

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

    除KO核心类库外,无依赖。

    event 绑定

    目的

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

    Mouse over me

    Details

    每次鼠标在第一个元素上移入移出的时候都会调用view model上的方法来toggle detailsEnabled的值,而第二个元素会根据detailsEnabled的值自动显示或者隐藏。 参数 主参数

    你需要传入的是一个JavaScript对象,他的属性名是事件名称,值是你所需要执行的函数。 你可以声明任何JavaScript函数 – 不一定非要是view model里的函数。你可以声明任意对象上的任何函数,例如: event: { mouseover: someObject.someFunction }。

    View model上的函数在用的时候有一点点特殊,就是不需要引用对象的,直接引用函数本身就行了,比如直接写event: { mouseover: enableDetails }就可以了,而无需写成:event: { mouseover: viewModel.enableDetails }(尽管是合法的)。 其它参数 无

    注1:传参数给你的click 句柄

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

    这样,KO就会调用这个匿名函数,里面会执行viewModel.myFunction(),并且传进了'param1' 和'param2'参数。 注2:访问事件源对象

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

    Mouse over me

    如果你需要的话,可以使用匿名函数的第一个参数传进去,然后在里面调用:

    Mouse over me

    这样,KO就会将事件源对象传递给你的函数并且使用了。 注3: 允许执行默认事件

    默认情况下,Knockout会阻止冒泡,防止默认的事件继续执行。例如,如果在一个input标签上绑定一个keypress事件,当你输入内容的时候,浏览器只会调用你的函数而不是天价你输入的值。另外一个例子click绑定,当你点击一个a连接,在执行完自定义事件时它不会连接到href地址。因为你的自定义事件主要就是操作你的view model,而不是连接到另外一个页面。

    当然,如果你想让默认的事件继续执行,你可以在你event的自定义函数里返回true。 注4:控制this句柄

    初学者可以忽略这小节,因为大部分都用不着,高级用户可以参考如下内容:

    KO在调用你定义的event绑定函数时,会将view model传给this对象(也就是ko.applyBindings使用的view model)。主要是方便你在调用你在view model里定义的方法的时候可以很容易再调用view model里定义的其它属性。例如:this.someOtherViewModelProperty。 如果你想引用其它对象,我们有两种方式:

     

    你可以和注1里那样使用匿名函数,因为它支持任意JavaScript 对象。

    你也可以直接引用任何函数对象。你可以使用bind使callback函数设置this为任何你选择的对象。例如:

    Mouse over me

    如果你是C#或Java开发人员,你可以疑惑为什么我们还要用bind函数到一个对象想,特别是像调用someObject.someFunction。原因是在JavaScript里,函数自己不是类的一部分,他们在单独存在的对象,有可能多个对象都引用同样的someFunction函数,所以当这个函数被调用的时候它不知道谁调用的(设置this给谁)。在你bind之前运行时是不会知道的。KO默认情况下设置this对象是view model,但你可以用bind语法重定义它。

    在注1里使用匿名函数的时候没有具体的要求,因为JavaScript代码 someObject.someFunction()就意味着调用someFunction,然后设置this到 someObject对象上。 注5:防止事件冒泡

    默认情况下,Knockout允许event事件继续在更高一层的事件句柄上冒泡执行。例如,如果你的元素和父元素都绑定了mouseover事件,那么如果你的鼠标在该元素移动的时候两个事件都会触发的。如果需要,你可以通过额外的绑定youreventBubble来禁止冒泡。例如:

    默认情况下,myButtonHandler会先执行,然后会冒泡执行myDivHandler。但一旦你设置了mouseoverBubble为false的时候,冒泡事件会被禁止。 依赖性

    除KO核心类库外,无依赖。

    submit 绑定

    目的

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

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

    ... form contents go here ...

    这个例子里,KO将把整个form表单元素作为参数传递到你的submit绑定函数里。你可以忽略不管,但是有些例子里是否有用,参考:ko.postJson工具。

    为什么不在submit按钮上使用click绑定?

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

    你绑定到submit事件上的函数

    你可以声明任何JavaScript函数 – 不一定非要是view model里的函数。你可以声明任意对象上的任何函数,例如:submit: someObject.someFunction。

    View model上的函数在用的时候有一点点特殊,就是不需要引用对象的,直接引用函数本身就行了,比如直接写submit: doSomething就可以了,而无需写成:submit: viewModel. doSomething(尽管是合法的)。 其它参数 无 备注:

    关于如果传递更多的参数给submit绑定函数,或者当调用非view model里的函数的时如何控制this,请参考click绑定。所有click绑定相关的notes也都适用于submit绑定。 依赖性

    除KO核心类库外,无依赖。

    enable 绑定

    目的

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

    I have a cellphone

    Your cellphone number:

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

    声明DOM元素是否可用enabled。

    非布尔值会被解析成布尔值。例如0和null被解析成false,21和非null对象被解析给true。 如果你的参数是observable的,那绑定会随着observable值的改变而自动更新enabled/disabled状态。如果不是,则只会设置一次并且以后不再更新。 其它参数 无

    注:任意使用JavaScript表达式

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

    依赖性

    除KO核心类库外,无依赖。

    disable 绑定

    目的

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

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

    value 绑定

    目的

    value绑定是关联DOM元素的值到view model的属性上。主要是用在表单控件