zoukankan      html  css  js  c++  java
  • KnockoutJs学习笔记(一)

    由于工作需要,接触到了Knockout,但是之前对于前台开发真的是不太了解,只能是摸着石头过河,边学边实践了。

    Knockout的官方网站是:http://knockoutjs.com/。我也是跟着官网上的文档一步步学习。

    本篇文章中的测试主要就是依据官网文档中的Creating view models with observables部分来进行的。

    首先,我依照创建view model的方式,在js文件中创建了自己的view model:

    1 var myViewModel = {
    2     name: "Yuki Nagato",
    3     age: 15
    4 };

    随后在相应的html文件中写了些简短的测试段落:

    1 <body>
    2 <h3>My test for knockoutJs(I don't know if it is right to write like this, haha)</h3>
    3 <p>Test start:<span data-bind="text: name"></span></p>
    4 </body>

    此时如果直接在浏览器中浏览html文件的话是不会看到任何结果的,还需要激活Knockout,按照官网的说法,就是Activating Knockout,于是在js文件后又添加了新的一行:

    1 ko.applyBindings(myViewModel);

    嗯,由于博主对于js的知识了解的真的很少,此时就直接想在浏览器中看到效果,结果页面显示如下:

    而chrome的developer tools中显示:

    于是在stackoverflow中找到了相应的问题,发现是这样一个问题:

    提问者在这里采用的是在html文件中的script元素内添加defer属性的方式,这种属性我之前并没有见过,可以留作以后研究,但是另一种解决方式似乎更具有普遍性。现在jQuery的使用频率很高,jQuery中的ready部分详细描述了在使用jQuery的同时解决这种DOM与script载入顺序的方法,具体的文档在http://api.jquery.com/ready/。ready的作用在于指定相应的javascript function在DOM完全载入成功以后执行,javascript中似乎提供的是load事件,可以留作以后研究

    按照文档中的描述,有三种编写方式:

    • $( document ).ready( handler )
    • $().ready( handler ) (这种方式不推荐)
    • $( handler )

    显然第三种方式最为简便,所以通用性也更强,一般的格式如下:

    1 $(function() {
    2     // Handler for .ready() called.
    3 });

    当然,文档中还提到了onload属性和ready的兼容性问题以及jQuery的命名空间问题,由于不涉及我现在要用的东西,可以留作以后研究

    这样一来,我的js文件就变成了这样:

    1 $(function() {
    2     var myViewModel = {
    3     name: "Yuki Nagato",
    4     age: 15
    5     };
    6 
    7     ko.applyBindings(myViewModel);
    8 });

    当然,我也在html文件中添加了jQuery文件的链接,而浏览器中也成功显示出了view model中的name属性:

    而在Knockout的文档中也提到说ko.applyBindings这个函数的参数可以有两个,第一个用于声明你用来激活declarative bingdings的view model,第二个则可以通过指定相应的selector来选择性的绑定view model,这里我做了一个测试,将html文件改成这样:

    1 <p>Name: <span id="name" data-bind="text: name"></span></p>
    2 <p>Age: <span data-bind="text: age"></span></p>

    js文件则改成了这样:

    1 ko.applyBindings(myViewModel, document.getElementById("name"));

    随后页面显示如下:

    可以看到,我们仅仅激活了相应ID的元素,不知道选取DOM node能不能通过jQuery的方式,应该会更为简便一些

    之前的例子里,我仅仅是在页面中展现了view model的属性,但KO的关键优势就在于它能够根据view model的变化来自动更新UI(页面)的变化。为了能让KO知晓view model的变化,我们需要在view model中将相应的属性声明为observable,它是一种特殊的能够通知订阅者相应的改变,并能够自动探测相应的依赖关系的javascript object。于是,我的js文件更新如下:

    1 $(function() {
    2     var myViewModel = {
    3     name: ko.observable("Yuki Nagato"),
    4     age: ko.observable(15)
    5     };
    6 
    7     ko.applyBindings(myViewModel);
    8 });

    而获取或是修改observable的值也是极为方便的,在js文件中添加如下几行:

    1 myViewModel.age(20);
    2 var name = myViewModel.name();
    3 $("#getValueOfOB").text(name);

    在html文件中再添加一个p元素:

    1 <p>Test for getting the value of observable: <span id="getValueOfOB"></span></p>

    这是可以在页面中看到相应的效果:

    可以看出js中对view model修改的代码与applybindings之间的顺序没有没什么关系,在其之前其之后都可行。同时也可以采用链式语法来修改多个view model属性:

    1 myViewModel.name("Kazusa Touma").age(16);

    当然,也可以自己定义相应的function来响应observable的变化,最简单的例子如下:

    1 myViewModel.name.subscribe(function(newName) {
    2   alert("The new name is " + newName);
    3 });
    4 myViewModel.name("Chiaki Izumi"););

     

    需要注意的是,对相应observable的修改应当在自定义的subscribe function之后出现。而subscribe function可以接受三个参数,第一个是callback,作为observable改变时的相应处理;第二个是target(optional),可以指定callback function中的"this"的值;第三个是event(optional, default is "change"),作为callback function所需要响应的事件类型。

    比如,我们可以将event更改为"beforeChange",即在observable更改之前进行自定义的操作,代码和页面显示如下:

    1 var mySubscription = myViewModel.name.subscribe(function(oldName) {
    2   alert("The old name is " + oldName);
    3 }, null, "beforeChange");

    当然,我们自己也可以终止自定义的subscription:

    1 var mySubscription = myViewModel.name.subscribe(function(newName) {
    2   alert("The new name is " + newName);
    3 });
    4 mySubscription.dispose();

    这样一来,之后对observable的修改并不会触发我们自定义的subscribe function。

    最后,该部分的文档也提到说我们可以强制订阅observable相应的改变(即便新的值和原先的值一样也会提醒),为了测试这一功能,我采用了自定义的subscribe function:

     1 var myBeforeSubscription = myViewModel.name.subscribe(function(oldName) {
     2   alert("The old name is " + oldName);
     3 }, null, "beforeChange");
     4 
     5 var mySubscription = myViewModel.name.subscribe(function(newName) {
     6   alert("The new name is " + newName);
     7 });
     8 
     9 myViewModel.name.extend({ notify: "always" });
    10 
    11 myViewModel.name("Kazusa Touma");

    我们可以看到页面产生这样的结果:

    另外,通过extend方法,我们也可以为订阅设定一个延时:

    1 myViewModel.name.extend({ rateLimit: 5000 });

    需要注意的是,这个延时是更改的延时,也就是将view model同步到UI的时间上的延时,而对于针对"beforeChange"事件的自定义subscribe function,它们会直接触发(不会涉及延时)。比如说我将延时设置为5秒,并且设定了两个自定义的subscribe function,一个的event是"beforeChange",另一个event是默认的"change",在页面载入后,beforeChange的function会直接执行,而change的function则会在5秒之后执行。

  • 相关阅读:
    网页中插入Flash动画(.swf)代码和常用参数设置
    关于UML中逻辑模型的工具的详细介绍
    简单CSS hack:区分IE6、IE7、IE8、Firefox、Opera
    mysql sock找不到
    简述nginx日志管理切割日志(亲测可行)
    Linux下使用rm删除文件,并排除指定文件(亲测可行)
    常驻内存以及如何避免内存泄漏
    TASK异步进程处理场景
    TCP长连接数据传输(同步方式)
    在智联上投了一个月的简历,很多都有意向,但是却没有通知我去
  • 原文地址:https://www.cnblogs.com/charlieyuki/p/3926858.html
Copyright © 2011-2022 走看看