knockout学习笔记

学习knockout路程中记下的一些容易遗忘和稍微难理解的知识点,学习地址“knockout.js爱整理
1.<!–ko–>和<!–/ko–>的用法
有时你可能需要使用Knockout在不使用多余的元素的情况下通过text绑定来设置文本内容。例如,在option元素中是不允许存在其他元素的,所以下面的绑定是无法正常工作的。

<select data-bind="foreach: items">
    <option>Item<span data-bind="text: name"></span></option>
</select>

为了解决这个问题,你可以使用容器语法,它基于一个注释元素。

<select data-bind="foreach: items"> 
    <option>Item<!--ko text: name--><!--/ko--></option>
</select>

<!–ko–>和<!–/ko–>注释标记作为起始和结束符,定义一个“虚拟元素”,里面包含了标记,Knockout能够识别这种虚拟元素语法和绑定作为你需要的容器元素而存在。

2.css类名绑定时参数是一个对象

<div data-bind="css: { profitWarning: currentProfit() < 0 }">
   Profit Information
</div>

<script type="text/javascript">
    var viewModel = {
        currentProfit: ko.observable(150000) // Positive value, so initially we don't apply the "profitWarning" class
    };
    viewModel.currentProfit(-50); // Causes the "profitWarning" class to be applied
</script>

    效果就是当currentProfit 小于0的时候,添加profitWarning CSS class到元素上,如果大于0则删除这个CSS class。
    再看一个visible绑定:

<div data-bind="visible: shouldShowMessage">
    You will see this message only when "shouldShowMessage" holds a true value.
</div>

<script type="text/javascript">
    var viewModel = {
        shouldShowMessage: ko.observable(true) // Message initially visible
    };
    viewModel.shouldShowMessage(false); // ... now it's hidden
    viewModel.shouldShowMessage(true); // ... now it's visible again
</script>

    可以看出css绑定和之前的visible,text,html绑定不同,这些绑定的参数都是对view model的ko对象中的属性。而css绑定参数则是一个对象,这个对象的属性是CSS class名称,值是比较用的true或false,用来决定是否应该使用这个class。也可以一次设置多个CSS class:

<div data-bind="css: { profitWarning: currentProfit() < 0, majorHighlight: isSevere }">

不仅仅css绑定参数是一个对象,后面还有类型绑定也是这样。

3.style绑定中变量命名规范
    我们绑定颜色属性时可以直接使用color,那如果是font-weight呢,直接使用就错了。这个规范和在js中修改某个元素的样式命名一样。

{color: someValue}  // 正确
{font-weight: someValue}  // 错误
{fontWeight: someValue}  // 正确

4.foreach绑定
先po代码(刚开始我很难理解它的):

<table>
    <thead>
        <tr><th>First name</th><th>Last name</th></tr>
    </thead>
    <tbody data-bind="foreach: people">
        <tr>
            <td data-bind="text: firstName"></td>
            <td data-bind="text: lastName"></td>
        </tr>
    </tbody>
</table>
<script type="text/javascript">
    ko.applyBindings({
        people: [
            { firstName: 'Bert', lastName: 'Bertington' },
            { firstName: 'Charles', lastName: 'Charlesforth' },
            { firstName: 'Denise', lastName: 'Dentiste' }
        ]
    });

</script>

显示效果:
这里写图片描述
将js代码稍微改变一下:

<script type="text/javascript">
    var viewModel = {
        people: [
            {
                firstName: 'Bert',
                lastName: 'Bertington'
            },
            {
                firstName: 'Charles',
                lastName: 'Charlesforth'
            },
            {
                firstName: 'Denise',
                lastName: 'Dentiste'
            }
        ]
    };
    ko.applyBindings(viewModel);
</script>

    把结构梳理出来,这样就好理解一点了。首先要注意的就是people不是一个监控属性数组,所以是One-Time绑定。people绑定到tbody,它是一个数组,遍历数组的每一个元素,这里的每一个元素就是一个对象。一个元素对应一个tr,页面结构中只需要写一个tr就行,数组中有几个元素就生成几个tr(好厉害呀这样)。然后数组中每个对象的属性在绑定到td中,就大功告成了。(ko牛逼)

5.foreach绑定中as起别名的用法
    我们可以使用$data来代替数组中的元素,同时我们也可以使用as来为我们要遍历的元素起一个别名。在使用的时候我们要注意,起别名使用的是as:’category’而不是as:category。
view代码:

<ul data-bind="foreach: {data: categories, as: 'category'}">
    <li>
        <ul data-bind="foreach: {data: items, as: 'item'}">
            <li>
                <span data-bind="text: category.name"></span>:
                <span data-bind="text: item"></span>
            </li>
        </ul>
    </li>
</ul>

view model代码:

<script type="text/javascript">
    var viewModel = {
        categories: ko.observableArray([
            { name: 'Fruit', items: [ 'Apple', 'Orange', 'Banana' ] },
            { name: 'Vegetables', items: [ 'Celery', 'Corn', 'Spinach' ] }
        ])
    };
    ko.applyBindings(viewModel);
</script>

显示效果:
这里写图片描述
    但是为什么一定要使用as呢?如果不使用as会怎么样呢?还有绑定name的时候为什么要这样category.name使用呢,直接用name不行吗?请看修改过后的view部分:

<ul data-bind="foreach: categories">
    <li>
        <ul data-bind="foreach: items">
            <li>
                <span data-bind="text: categories.name"></span>:
                <span data-bind="text: items"></span>
            </li>
        </ul>
    </li>
</ul>

    直接报一万行错罒ω罒,哭哭惹。可是为什么不行呢,仔细看这一句话“使用as来为我们要遍历的元素起一个别名”。也就是说这里用as定义别名是给遍历的元素起的,并不是categories这个监控数组,而是数组里面的每个元素(也不能这么说,应该是遍历时代表的那个元素)。
    所以category.name也就很容易理解了,category是遍历时的那个项,而外面的大数组的每一项是json对象,取到json中的值那就是jsonName.attr(对象名.属性)啦。那为什么之前都没有这样写呢,该代码试试咯:

<ul data-bind="foreach: { data: categories, as: 'category' }">
    <li>
        <!-- ko text: name--><!-- /ko -->
        <ul data-bind="foreach: { data: items, as: 'item' }">
            <li>
                <span data-bind="text: name"></span>:
                <span data-bind="text: item"></span>
            </li>
        </ul>
    </li>
</ul>

效果:
这里写图片描述
    这样就可以很好的解释了,<span data-bind=”text: name”></span>这里如果直接用name绑定的话,应该就是在items这个数组的每项中寻找‘name’这个属性,找到个空气咯。再看这行代码<!– ko text: name–><!– /ko –>,处于第二个foreach外面,就可以直接使用name绑定,因为category这个json对象是有’name’属性的。

这个文档是我自己原创制作的,在别的网上肯定是没有的。 而且做得非常好看,和非常准确。 如果下载的人多,将会把中英文对照的版本也上传。 Knockout是一个以数据模型(data model)为基础的能够帮助你创建富文本,响应显示和编辑用户界面的JavaScript类库。任何时候如果你的UI需要自动更新(比如:更新依赖于用户的行为或者外部数据源的改变),KO能够很简单的帮你实现并且很容易维护。 重要特性: 优雅的依赖追踪 - 不管任何时候你的数据模型更新,都会自动更新相应的内容。 Elegant dependency tracking - automatically updates the right parts of your UI whenever your data model changes. 声明式绑定 - 浅显易懂的方式将你的用户界面指定部分关联到你的数据模型上。 Declarative bindings - a simple and obvious way to connect parts of your UI to your data model. You can construct a complex dynamic UIs easily using arbitrarily nested binding contexts. 轻易可扩展 - 几行代码就可以实现自定义行为作为新的声明式绑定。 Trivially extensible - implement custom behaviors as new declarative bindings for easy reuse in just a few lines of code. 额外的好处: 纯JavaScript类库 – 兼容任何服务器端和客户端技术 Pure JavaScript library - works with any server or client-side technology 可添加到Web程序最上部 – 不需要大的架构改变 Can be added on top of your existing web application - without requiring major architectural changes 简洁的 - Gzip之前大约25kb Compact - around 13kb after gzipping 兼容任何主流浏览器 - (IE 6+、Firefox 2+、Chrome、Safari、其它) Works on any mainstream browser - (IE 6+, Firefox 2+, Chrome, Safari, others) 采用行为驱动开发 - 意味着在新的浏览器和平台上可以很容易通过验证。 Comprehensive suite of specifications - (developed BDD-style) means its correct functioning can easily be verified on new browsers and platforms 开发人员如果用过Silverlight或者WPF可能会知道KO是MVVM模式的一个例子。如果熟悉 Ruby on Rails 或其它MVC技术可能会发现它是一个带有声明式语法的MVC实时form。换句话说,你可以把KO当成通过编辑JSON数据来制作UI用户界面的一种方式… 不管它为你做什么 Developers familiar with Ruby on Rails, ASP.NET MVC, or other MV* technologies may see MVVM as a real-time form of MVC with declarative syntax. In another sense, you can think of KO as a general way to make UIs for editing JSON data… whatever works for you :) OK, 如何使用它? 简单来说:声明你的数据作为一个JavaScript 模型对象(model object),然后将DOM 元素或者模板(templates)绑定到它上面. The quickest and most fun way to get started is by working through the interactive tutorials. Once you’ve got to grips with the basics, explore the live examples and then have a go with it in your own project. KO和jQuery (或Prototype等)是竞争关系还是能一起使用? 所有人都喜欢jQuery! 它是一个在页面里操作元素和事件的框架,非常出色并且易使用,在DOM操作上肯定使用jQuery,KO解决不同的问题。 Everyone loves jQuery! It’s an outstanding replacement for the clunky, inconsistent DOM API we had to put up with in the past. jQuery is an excellent low-level way to manipulate elements and event handlers in a web page. I certainly still use jQuery for low-level DOM manipulation. KO solves a different problem. 如果页面要求复杂,仅仅使用jQuery需要花费更多的代码。 例如:一个表格里显示一个列表,然后统计列表的数量,Add按钮在数据行TR小于5调的时候启用,否则就禁用。jQuery 没有基本的数据模型的概念,所以需要获取数据的数量(从table/div或者专门定义的CSS class),如果需要在某些SPAN里显示数据的数量,当添加新数据的时候,你还要记得更新这个SPAN的text。当然,你还要判断当总数>=5条的时候禁用Add按钮。 然后,如果还要实现Delete功能的时候,你不得不指出哪一个DOM元素被点击以后需要改变。 As soon as your UI gets nontrivial and has a few overlapping behaviors, things can get tricky and expensive to maintain if you only use jQuery. Consider an example: you’re displaying a list of items, stating the number of items in that list, and want to enable an ‘Add’ button only when there are fewer than 5 items. jQuery doesn’t have a concept of an underlying data model, so to get the number of items you have to infer it from the number of TRs in a table or the number of DIVs with a certain CSS class. Maybe the number of items is displayed in some SPAN, and you have to remember to update that SPAN’s text when the user adds an item. You also must remember to disable the ‘Add’ button when the number of TRs is 5. Later, you’re asked also to implement a ‘Delete’ button and you have to figure out which DOM elements to change whenever it’s clicked. Knockout的实现有何不同? 使用KO非常简单。将你的数据描绘成一个JavaScript数组对象myItems,然后使用模板(template)转化这个数组到表格里(或者一组DIV)。不管什么时候数组改变, UI界面也会响应改变(不用指出如何插入新行或在哪里插入),剩余的工作就是同步了。例如:你可以声明绑定如下一个SPAN显示数据数量(可以放在页面的任何地方,不一定非要在template里): It’s much easier with KO. It lets you scale up in complexity without fear of introducing inconsistencies. Just represent your items as a JavaScript array, and then use a foreach binding to transform this array into a TABLE or set of DIVs. Whenever the array changes, the UI changes to match (you don’t have to figure out how to inject new TRs or where to inject them). The rest of the UI stays in sync. For example, you can declaratively bind a SPAN to display the number of items as follows: There are <span data-bind="text: myItems().count"></span> items就是这些!你不需要写代码去更新它,它的更新依赖于数组myItems的改变。同样, Add按钮的启用和禁用依赖于数组 myItems 的长度,如下: That’s it! You don’t have to write code to update it; it updates on its own when the myItems array changes. Similarly, to make the ‘Add’ button enable or disable depending on the number of items, just write: <button data-bind="enable: myItems().count < 5">Add</button>之后,如果你要实现Delete功能,不必指出如何操作UI元素,只需要修改数据模型就可以了。 Later, when you’re asked to implement the ‘Delete’ functionality, you don’t have to figure out what bits of the UI it has to interact with; you just make it alter the underlying data model. 总结:KO没有和jQuery或类似的DOM 操作API对抗竞争。KO提供了一个关联数据模型和用户界面的高级功能。KO本身不依赖jQuery,但是你可以一起同时使用jQuery, 生动平缓的UI改变需要真正使用jQuery。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值