学习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’属性的。