zoukankan      html  css  js  c++  java
  • 4.Knockout.Js(事件绑定)

    前言

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

    简单示例

    复制代码
    <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(尽管是合法的)。

    传参数给你的click 句柄

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

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

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

    访问事件源对象

     有些情况,你可能需要使用事件源对象,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绑定。

  • 相关阅读:
    Linux 学习 step by step (1)
    ubuntu server nginx 安装与配置
    ubuntu server samba服务器配置
    iOS app集成支付宝支付流程及后台php订单签名处理
    mac 连接windows 共享内容
    linux 文件查找,which,whereis,locate,find
    ubuntu server vsftpd 虚拟用户及目录
    ubuntu server 安装 mantis bug tracker 中文配置
    ubuntu server vsftpd 匿名用户上传下载及目录设置
    linux 用户管理,用户权限管理,用户组管理
  • 原文地址:https://www.cnblogs.com/TF12138/p/4156919.html
Copyright © 2011-2022 走看看