创建自定义模板
1、注册绑定
添加子属性到ko.bindingHandlers.yourBindingName ={};注册绑定。
init和update可以只定义其中一个。
(1)初始化:init
// 建立初始化状态,事件处理等等
(2)更新:update
// 无论何时相关联的observable改变value时候
// 基于应用values的DOM元素
(3)在DOM元素上使用: <div data-bind="yourBindingName:
someValue"></div>
2、详细解释
ko.bindingHandlers.yourBindingName ={
init:function
(element,valueAccessor,allBindingsAccessor,viewModel){},
update:function
(element,valueAccessor,allBindingsAccessor,viewModel)
}
参数:
element——使用这个绑定的DOM元素。
valueAccessor——Javascript函数。通过valueAccessor()可以得到应用到这个绑定的model上的当前属性值。
另一种翻译:得到是当前进入绑定的内容。是observable不是值。可以是表达式的值。
allBindingsAccessor--Javascript函数。通过allBindingsAccessor()得到这个元素上所有model的属性值。
另一种翻译:得到其他绑定,并列入绑定属性中。一般用来访问其他绑定。这使您可以访问所有的其他绑定在同一列数据绑定属性。这通常是用于访问其他与此结合相互作用的绑定。这些绑定可能不会有任何相关的代码,只是一种方法,通过附加选项的约束力,除非你选择的多个属性为您的主要结合传递一个对象。例如,optionsvalue,optionstext,和optionscaption是绑定,只能通过选项选项结合。
(1) init回调:
knockout在dom元素使用自定义绑定的时候会调用你的init函数。 init有两个重要的用途:为dom元素设置初始值;注册事件句柄,例如当用户点击或者编辑DOM元素的时候,可以改变相关的observable值的状态。ko会传递和update回调函数一样的参数。
你可以像让slideVisible在页面第一次显示的时候设置该元素的状态(但是不使用任何动画效果),而只是让动画在以后改变的时候再执行。
你可以这样来做:
ko.bindingHandlers.slideVisible = {
init: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor
());
// Get the current value of the current property we're
bound to
$(element).toggle(value);
// jQuery will hide/show the element depending on
whether "value" or true or false
},
update: function(element, valueAccessor,
allBindingsAccessor) {
// Leave as before
}
};
这就是说giftWrap的初始值声明的是false(例如giftWrap: ko.observable(false)),然后让初始值会让关联的DIV隐藏,之后用户点击checkbox的时候会让元素显示出来。
(2)update回调
通过visible绑定来控制一个元素的可见性,但是想让该元素在隐藏或者显示的时候加入动画效果。可以自定义自己的绑定来调用jquery的slideUp/slideDown函数。
ko.bindingHandlers.slideVisible = {
update: function
(element,valueAccessor,allBindingsAccessor){
// get the latest data that bound to
var value = valueAccessor(), allBindings =
allBindingsAccessor();
// next,whether or not the supplied model property is
observable,get its current value.
var valueUnwrapped = ko.utils.unwrapObservable(value);
// grab some more data from another bingding property
var duration = allBindings.slideDuration || 500;
// 500 is default duration unless otherwise specified
// now manipulate the dom element
if(valueUnwrapped == true) $(element).slideDown(duration);
else $(element).slideUp(duration);
}
};
1、数组绑定
this.items = ko.observableArray([
{ id: 1, name: "Apple Pie" },
{ id: 2, name: "Pumpkin Pie" },
{ id: 3, name: "Blueberry Torte" }
]);
this.items.push({ id: 4, "Strawberry Shortcake" });
重要是要注意,ObservableArrays跟踪数组里的item更改,而不是单独的一个item的属性。在上面的例子中,如果你的应用需要跟踪item的name,那么name属性需要也加一个observable。
2、在IE6下,如果有空格要写 否则不呈现空格。
一、控制文本和展现
1、text绑定
2、visible绑定
3、html绑定
<div data-bind="html: details"></div>
<script type="text/javascript">
var viewModel = {
details: ko.observable() // Initially blank
};
viewModel.details("<em>For further details, view the
report <a href='report.html'>here</a>.</em>"); // HTML content
appears
</script>
4、如果你提供的不是数字或者字符串,你传递的是对象或数组等,innerHTML/text bingding和yourParameter.toString()效果一样。
5、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时,css样式名"profitWarning"就增加,否则移除这个css。
动态切换两个css:
<div data-bind="css: profitStatus">
Profit Information
</div>
<script type="text/javascript">
var viewModel = {
currentProfit: ko.observable(150000)
};
// Evalutes to a positive value, so initially we apply the
"profitPositive" class
viewModel.profitStatus = ko.computed(function() { //
computed
return this.currentProfit() < 0 ? "profitWarning" :
"profitPositive";
}, viewModel);
// Causes the "profitPositive" class to be removed and
"profitWarning" class to be added
viewModel.currentProfit(-50);
</script>
可以同时使用多个css绑定:
<div data-bind="css: { profitWarning: currentProfit() < 0, majorHighlight: isSevere }">
当类标志不合法时,如profitWarning,给其加上引号:'profitWarning'
6、style 绑定
<div data-bind="style: { color: currentProfit() < 0 ? 'red' :
'black', fontWeight: isSevere() ? 'bold' : '' }">...</div>
7、attr绑定
<a data-bind="attr: { href: url, title: details }">
Report
</a>
<script type="text/javascript">
var viewModel = {
url: ko.observable("year-end.html"),
details: ko.observable("Report including final year-
end statistics")
};
</script>
attr属性名字不合法时,加上引号就可以。
二、控制流绑定
1、foreach绑定
foreach绑定复制进入一个数组的标记部分,绑定每一个复制标记到相应的数组条目。可以和其他控制流的if、with一起使用。
<h4>People</h4>
<ul data-bind="foreach: people">
<li>
Name at position <span data-bind="text: $index">
</span>:
<span data-bind="text: name"> </span>
<a href="#" data-bind="click:
$parent.removePerson">Remove</a>
</li>
</ul>
<button data-bind="click: addPerson">Add</button>
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());
$index:序号
$parent:上一级元素
(1)$data
foreach块可以在数组项引用属性,但是如果希望在数组条目本身时引入属性:
用$data代表每一项。
显示每一项的具体内容:
<td data-bind="text: $data.firstName"></td>
(2)别名:as,加上引号,是给一个新名字为新的变量,不是改变值。
任何foreach循环内部,都会引用别名进入现在的数组条目。这在祖先元素已经嵌套foreach块,而且你需要在更高一层引用一个条目声明时很有用。
<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>
<script>
var viewModel = {
categories: ko.observableArray([
{ name: 'Fruit', items: [ 'Apple', 'Orange',
'Banana' ] },
{ name: 'Vegetables', items: [ 'Celery', 'Corn',
'Spinach' ] }
])
};
ko.applyBindings(viewModel);
</script>
(3)只有部分元素循环遍历,加上包裹元素在内部(如例子中的span标签)。使用<!---->
<ul>
<li class="header">Header item</li>
<!-- ko foreach: myItems -->
<li>Item <span data-bind="text: $data"></span></li>
<!-- /ko -->
</ul>
<script type="text/javascript">
ko.applyBindings({
myItems: [ 'A', 'B', 'C' ]
});
</script>
(4)想要显示销毁的条目,使用includeDestroyed
<div data-bind='foreach: { data: myArray, includeDestroyed:
true }'>
...
</div>
(5)执行动画效果
afterRender/afterAdd/beforeRemove/beforeMove/afterMove
<ul data-bind="foreach: { data: myItems, afterAdd:
yellowFadeIn }">
<li data-bind="text: $data"></li>
</ul>
<button data-bind="click: addItem">Add</button>
<script type="text/javascript">
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'); }
});
</script>
afterRender: 在foreach块复制到文档中或foreach初始化,或新的条
目增加到数组中,konckout将会提供如下参数到回调函数中:
插入到数组中的dom元素
对应被绑定的数据条目
afterAdd:当新条目增加到数组中时激发。一般用来回调一个方法,比如$().fadeIn(),得到动画过度当条目增加时。knockout会提供如下参数:
被增加的dom节点,增加的数组元素index,增加的数组元素
beforeMove:当数组条目在数组中的位置发生改变,且在对应dom节点被移除前 被激发。它适用于所有序号改变的数组元素,所以当你插入一个数组条目在数组中,回调函数会激发其他元素,知道他们的序号位置已经增加了1。可以使用beforeMove来存储收影响元素的原始屏幕坐标。这样你可以使他们在afterMove回调函数中动画过度。
提供的回调参数:
将要移动的dom节点,移动的数组元素的序号,移动的数组元素。
afterMove:当数组中的数组条目已经改变位置时,在foreach已经更新dom来匹配之后,被激发。
afterMove适用于所有序号被改变的数组元素,回调函数会激发其他元素,直到他们的序号位置都已经增加一。
konockout提供的回调参数:
将要被移除的dom节点,移动的数组元素的序号,移动的数组元素。
2、if绑定
if和visible
if和visible差不多。不同在于,使用visible,包括标签保持在dom中,经常使用data-bind属性——visible绑定使用css来切换标签的可见性。if只在表达式为真的情况下适用于增加或移除dom中绑定的后代元素包括的标签。
例子:
<ul data-bind="foreach: planets">
<li>
Planet: <b data-bind="text: name"> </b>
<div data-bind="if: capital">
Capital: <b data-bind="text: capital.cityName">
</b>
</div>
</li>
</ul>
<script>
ko.applyBindings({
planets: [
{ name: 'Mercury', capital: null },
{ name: 'Earth', capital: { cityName: 'Barnsley' }
}
]
});
</script>
在以上例子中,因为if,capital为null就不用继续执行,发生错误:
计算后续capital.cityName不存在的属性了。在javascript中,可以判断if:capital判断是否为空,但是不允许计算为空的值:
capital.cityName。
if后面的语句为true,显示包含的标签。
if后面的语句为false,包含的标签将会从document中移走而不是适用于任何刚开始的绑定。
如果表达式提及到任何可观测值,当它们改变时表达式会被重新计算。
相应的,带有if标签块将会动态增加和移除当表达式结果发生改变时。
data-bind属性将会被用于一个新的副本包含标签。
当想要实现控制某一部分标签显示隐藏,
使用<!-- ko --><!-- /ko -->
<ul>
<li>This item always appears</li>
<!-- ko if: someExpressionGoesHere -->
<li>I want to make this item present/absent
dynamically</li>
<!-- /ko -->
</ul>
3、ifnot绑定
和if一样。完全可以用if代替。
4、with绑定
with绑定创建了一个新的上下文,所以后代元素被绑定一个详细的对象上下文。
可以任意使用其他控制流绑定如if/foreach和嵌套with绑定。
以下是一个简单的切换绑定上下文到子对象。
注意data-bind属性,没有必要加上latitude和longitude的前缀
coords.。因为绑定上下文已经切换到coords了。
<h1 data-bind="text: city"> </h1>
<p data-bind="with: coords">
Latitude: <span data-bind="text: latitude"> </span>,
Longitude: <span data-bind="text: longitude"> </span>
</p>
<script type="text/javascript">
ko.applyBindings({
city: "London",
coords: {
latitude: 51.5001524,
longitude: -0.1262362
}
});
</script>
复杂一点的with例子:
<form data-bind="submit: getTweets">
Twitter account:
<input data-bind="value: twitterName" />
<button type="submit">Get tweets</button>
</form>
<div data-bind="with: resultData">
<h3>Recent tweets fetched at <span data-bind="text:
retrievalDate"> </span></h3>
<ol data-bind="foreach: topTweets">
<li data-bind="text: text"></li>
</ol>
<button data-bind="click: $parent.clearResults">Clear
tweets</button>
</div>
function AppViewModel() {
var self = this;
self.twitterName = ko.observable('@example');
self.resultData = ko.observable(); // No initial value
self.getTweets = function() {
var name = self.twitterName(),
simulatedResults = [
{ text: name + ' What a nice day.' },
{ text: name + ' Building some cool apps.' },
{ text: name + ' Just saw a famous celebrity
eating lard. Yum.' }
];
self.resultData({ retrievalDate: new Date(),
topTweets: simulatedResults });
}
self.clearResults = function() {
self.resultData(undefined);
}
}
ko.applyBindings(new AppViewModel());
with绑定动态增加移除后代元素依赖于联系的值是null/undefined或非空。
如果需要访问父元素绑定的上下文中的data/functions,可以使用
$parent和root。
关于with的子属性设置的两种写法:
1、写在viewmodel对象中
var viewModel ={
lcon: {
lname: "lfwefw ",
showCon: [
{ name: "s", textInput: "second" },
{ name: "t", textInput: "third" },
{ name: "f", textInput: "first" }]
}
}
2、用创建viewModel函数的写法
function AppViewModel() {
var self = this;
self.resultData({ retrievalDate: new Date(), topTweets:
simulatedResults });
}
与其他没有包括标签一样:
<ul>
<li>Header element</li>
<!-- ko with: outboundFlight -->
...
<!-- /ko -->
<!-- ko with: inboundFlight -->
...
<!-- /ko -->
</ul>
<title></title>
<script type="text/javascript" src="js/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="js/jquery.tmpl.js"></script>
<script type="text/javascript" src="js/knockout-3.1.0.js"></script>
<script type="text/javascript" src="js/knockout.simpleGrid.js"></script>
<style type="text/css">
</style>
</head>
<body>
<form data-bind="submit: showDetail">
<div>
Your Account:<input type="text" data-bind="value: inputCon" />
<button type="submit">提交信息</button>
</div>
</form>
<div data-bind="visible: hiddenDetail">
<div data-bind="text: inputCon"></div>
<div data-bind="with: lcon">
<div data-bind="text: lname"></div>
<div data-bind="foreach: showCon">
hello:<span data-bind="text: name"></span>
<span data-bind=" text: name"></span>
<br />
</div>
</div>
<button type="submit" data-bind="click: clearCon">隐藏</button>
</div>
<script type="text/javascript">
var viewModel = {
inputCon: ko.observable("@mail"),
showDetail: ko.observable(true),
hiddenDetail: ko.observable(false)
,
lcon: {
lname: "lfwefw ",
showCon: [
{ name: "s", textInput: "second" },
{ name: "t", textInput: "third" },
{ name: "f", textInput: "first" }]
}
};
viewModel.showDetail = function () { viewModel.hiddenDetail(true); }
viewModel.clearCon = function () { viewModel.hiddenDetail(false); }
ko.applyBindings(viewModel);
</script>
</body>
1、注册绑定
添加子属性到ko.bindingHandlers.yourBindingName ={};注册绑定。
init和update可以只定义其中一个。
(1)初始化:init
// 建立初始化状态,事件处理等等
(2)更新:update
// 无论何时相关联的observable改变value时候
// 基于应用values的DOM元素
(3)在DOM元素上使用: <div data-bind="yourBindingName:
someValue"></div>
2、详细解释
ko.bindingHandlers.yourBindingName ={
init:function
(element,valueAccessor,allBindingsAccessor,viewModel){},
update:function
(element,valueAccessor,allBindingsAccessor,viewModel)
}
参数:
element——使用这个绑定的DOM元素。
valueAccessor——Javascript函数。通过valueAccessor()可以得到应用到这个绑定的model上的当前属性值。
另一种翻译:得到是当前进入绑定的内容。是observable不是值。可以是表达式的值。
allBindingsAccessor--Javascript函数。通过allBindingsAccessor()得到这个元素上所有model的属性值。
另一种翻译:得到其他绑定,并列入绑定属性中。一般用来访问其他绑定。这使您可以访问所有的其他绑定在同一列数据绑定属性。这通常是用于访问其他与此结合相互作用的绑定。这些绑定可能不会有任何相关的代码,只是一种方法,通过附加选项的约束力,除非你选择的多个属性为您的主要结合传递一个对象。例如,optionsvalue,optionstext,和optionscaption是绑定,只能通过选项选项结合。
viewModel--传递给ko.applyBindings使用的view model参数,如果是模板内部的话,这个参数就是传递给模板的数据。
另一种翻译:通常以data代替避免混淆调用此参数数据。外模板绑定,这将提供对你的整体视图模型。在一个模板,这将被绑定到模板数据。例如,使用的模板的结合foreach选项时,视图模型参数会被设置为当前数组成员通过模板发送。大多数时候,valueaccessor会给你你想要的数据,而视图模型参数是特别有用,如果你需要一个对象是你的目标的时候,你的call/apply功能。
(1) init回调:
knockout在dom元素使用自定义绑定的时候会调用你的init函数。 init有两个重要的用途:为dom元素设置初始值;注册事件句柄,例如当用户点击或者编辑DOM元素的时候,可以改变相关的observable值的状态。ko会传递和update回调函数一样的参数。
你可以像让slideVisible在页面第一次显示的时候设置该元素的状态(但是不使用任何动画效果),而只是让动画在以后改变的时候再执行。
你可以这样来做:
ko.bindingHandlers.slideVisible = {
init: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor
());
// Get the current value of the current property we're
bound to
$(element).toggle(value);
// jQuery will hide/show the element depending on
whether "value" or true or false
},
update: function(element, valueAccessor,
allBindingsAccessor) {
// Leave as before
}
};
这就是说giftWrap的初始值声明的是false(例如giftWrap: ko.observable(false)),然后让初始值会让关联的DIV隐藏,之后用户点击checkbox的时候会让元素显示出来。
(2)update回调
通过visible绑定来控制一个元素的可见性,但是想让该元素在隐藏或者显示的时候加入动画效果。可以自定义自己的绑定来调用jquery的slideUp/slideDown函数。
ko.bindingHandlers.slideVisible = {
update: function
(element,valueAccessor,allBindingsAccessor){
// get the latest data that bound to
var value = valueAccessor(), allBindings =
allBindingsAccessor();
// next,whether or not the supplied model property is
observable,get its current value.
var valueUnwrapped = ko.utils.unwrapObservable(value);
// grab some more data from another bingding property
var duration = allBindings.slideDuration || 500;
// 500 is default duration unless otherwise specified
// now manipulate the dom element
if(valueUnwrapped == true) $(element).slideDown(duration);
else $(element).slideUp(duration);
}
};
1、数组绑定
this.items = ko.observableArray([
{ id: 1, name: "Apple Pie" },
{ id: 2, name: "Pumpkin Pie" },
{ id: 3, name: "Blueberry Torte" }
]);
this.items.push({ id: 4, "Strawberry Shortcake" });
重要是要注意,ObservableArrays跟踪数组里的item更改,而不是单独的一个item的属性。在上面的例子中,如果你的应用需要跟踪item的name,那么name属性需要也加一个observable。
2、在IE6下,如果有空格要写 否则不呈现空格。
一、控制文本和展现
1、text绑定
2、visible绑定
3、html绑定
<div data-bind="html: details"></div>
<script type="text/javascript">
var viewModel = {
details: ko.observable() // Initially blank
};
viewModel.details("<em>For further details, view the
report <a href='report.html'>here</a>.</em>"); // HTML content
appears
</script>
4、如果你提供的不是数字或者字符串,你传递的是对象或数组等,innerHTML/text bingding和yourParameter.toString()效果一样。
5、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时,css样式名"profitWarning"就增加,否则移除这个css。
动态切换两个css:
<div data-bind="css: profitStatus">
Profit Information
</div>
<script type="text/javascript">
var viewModel = {
currentProfit: ko.observable(150000)
};
// Evalutes to a positive value, so initially we apply the
"profitPositive" class
viewModel.profitStatus = ko.computed(function() { //
computed
return this.currentProfit() < 0 ? "profitWarning" :
"profitPositive";
}, viewModel);
// Causes the "profitPositive" class to be removed and
"profitWarning" class to be added
viewModel.currentProfit(-50);
</script>
可以同时使用多个css绑定:
<div data-bind="css: { profitWarning: currentProfit() < 0, majorHighlight: isSevere }">
当类标志不合法时,如profitWarning,给其加上引号:'profitWarning'
6、style 绑定
<div data-bind="style: { color: currentProfit() < 0 ? 'red' :
'black', fontWeight: isSevere() ? 'bold' : '' }">...</div>
7、attr绑定
<a data-bind="attr: { href: url, title: details }">
Report
</a>
<script type="text/javascript">
var viewModel = {
url: ko.observable("year-end.html"),
details: ko.observable("Report including final year-
end statistics")
};
</script>
attr属性名字不合法时,加上引号就可以。
二、控制流绑定
1、foreach绑定
foreach绑定复制进入一个数组的标记部分,绑定每一个复制标记到相应的数组条目。可以和其他控制流的if、with一起使用。
<h4>People</h4>
<ul data-bind="foreach: people">
<li>
Name at position <span data-bind="text: $index">
</span>:
<span data-bind="text: name"> </span>
<a href="#" data-bind="click:
$parent.removePerson">Remove</a>
</li>
</ul>
<button data-bind="click: addPerson">Add</button>
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());
$index:序号
$parent:上一级元素
(1)$data
foreach块可以在数组项引用属性,但是如果希望在数组条目本身时引入属性:
用$data代表每一项。
显示每一项的具体内容:
<td data-bind="text: $data.firstName"></td>
(2)别名:as,加上引号,是给一个新名字为新的变量,不是改变值。
任何foreach循环内部,都会引用别名进入现在的数组条目。这在祖先元素已经嵌套foreach块,而且你需要在更高一层引用一个条目声明时很有用。
<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>
<script>
var viewModel = {
categories: ko.observableArray([
{ name: 'Fruit', items: [ 'Apple', 'Orange',
'Banana' ] },
{ name: 'Vegetables', items: [ 'Celery', 'Corn',
'Spinach' ] }
])
};
ko.applyBindings(viewModel);
</script>
(3)只有部分元素循环遍历,加上包裹元素在内部(如例子中的span标签)。使用<!---->
<ul>
<li class="header">Header item</li>
<!-- ko foreach: myItems -->
<li>Item <span data-bind="text: $data"></span></li>
<!-- /ko -->
</ul>
<script type="text/javascript">
ko.applyBindings({
myItems: [ 'A', 'B', 'C' ]
});
</script>
(4)想要显示销毁的条目,使用includeDestroyed
<div data-bind='foreach: { data: myArray, includeDestroyed:
true }'>
...
</div>
(5)执行动画效果
afterRender/afterAdd/beforeRemove/beforeMove/afterMove
<ul data-bind="foreach: { data: myItems, afterAdd:
yellowFadeIn }">
<li data-bind="text: $data"></li>
</ul>
<button data-bind="click: addItem">Add</button>
<script type="text/javascript">
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'); }
});
</script>
afterRender: 在foreach块复制到文档中或foreach初始化,或新的条
目增加到数组中,konckout将会提供如下参数到回调函数中:
插入到数组中的dom元素
对应被绑定的数据条目
afterAdd:当新条目增加到数组中时激发。一般用来回调一个方法,比如$().fadeIn(),得到动画过度当条目增加时。knockout会提供如下参数:
被增加的dom节点,增加的数组元素index,增加的数组元素
beforeMove:当数组条目在数组中的位置发生改变,且在对应dom节点被移除前 被激发。它适用于所有序号改变的数组元素,所以当你插入一个数组条目在数组中,回调函数会激发其他元素,知道他们的序号位置已经增加了1。可以使用beforeMove来存储收影响元素的原始屏幕坐标。这样你可以使他们在afterMove回调函数中动画过度。
提供的回调参数:
将要移动的dom节点,移动的数组元素的序号,移动的数组元素。
afterMove:当数组中的数组条目已经改变位置时,在foreach已经更新dom来匹配之后,被激发。
afterMove适用于所有序号被改变的数组元素,回调函数会激发其他元素,直到他们的序号位置都已经增加一。
konockout提供的回调参数:
将要被移除的dom节点,移动的数组元素的序号,移动的数组元素。
2、if绑定
if和visible
if和visible差不多。不同在于,使用visible,包括标签保持在dom中,经常使用data-bind属性——visible绑定使用css来切换标签的可见性。if只在表达式为真的情况下适用于增加或移除dom中绑定的后代元素包括的标签。
例子:
<ul data-bind="foreach: planets">
<li>
Planet: <b data-bind="text: name"> </b>
<div data-bind="if: capital">
Capital: <b data-bind="text: capital.cityName">
</b>
</div>
</li>
</ul>
<script>
ko.applyBindings({
planets: [
{ name: 'Mercury', capital: null },
{ name: 'Earth', capital: { cityName: 'Barnsley' }
}
]
});
</script>
在以上例子中,因为if,capital为null就不用继续执行,发生错误:
计算后续capital.cityName不存在的属性了。在javascript中,可以判断if:capital判断是否为空,但是不允许计算为空的值:
capital.cityName。
if后面的语句为true,显示包含的标签。
if后面的语句为false,包含的标签将会从document中移走而不是适用于任何刚开始的绑定。
如果表达式提及到任何可观测值,当它们改变时表达式会被重新计算。
相应的,带有if标签块将会动态增加和移除当表达式结果发生改变时。
data-bind属性将会被用于一个新的副本包含标签。
当想要实现控制某一部分标签显示隐藏,
使用<!-- ko --><!-- /ko -->
<ul>
<li>This item always appears</li>
<!-- ko if: someExpressionGoesHere -->
<li>I want to make this item present/absent
dynamically</li>
<!-- /ko -->
</ul>
3、ifnot绑定
和if一样。完全可以用if代替。
4、with绑定
with绑定创建了一个新的上下文,所以后代元素被绑定一个详细的对象上下文。
可以任意使用其他控制流绑定如if/foreach和嵌套with绑定。
以下是一个简单的切换绑定上下文到子对象。
注意data-bind属性,没有必要加上latitude和longitude的前缀
coords.。因为绑定上下文已经切换到coords了。
<h1 data-bind="text: city"> </h1>
<p data-bind="with: coords">
Latitude: <span data-bind="text: latitude"> </span>,
Longitude: <span data-bind="text: longitude"> </span>
</p>
<script type="text/javascript">
ko.applyBindings({
city: "London",
coords: {
latitude: 51.5001524,
longitude: -0.1262362
}
});
</script>
复杂一点的with例子:
<form data-bind="submit: getTweets">
Twitter account:
<input data-bind="value: twitterName" />
<button type="submit">Get tweets</button>
</form>
<div data-bind="with: resultData">
<h3>Recent tweets fetched at <span data-bind="text:
retrievalDate"> </span></h3>
<ol data-bind="foreach: topTweets">
<li data-bind="text: text"></li>
</ol>
<button data-bind="click: $parent.clearResults">Clear
tweets</button>
</div>
function AppViewModel() {
var self = this;
self.twitterName = ko.observable('@example');
self.resultData = ko.observable(); // No initial value
self.getTweets = function() {
var name = self.twitterName(),
simulatedResults = [
{ text: name + ' What a nice day.' },
{ text: name + ' Building some cool apps.' },
{ text: name + ' Just saw a famous celebrity
eating lard. Yum.' }
];
self.resultData({ retrievalDate: new Date(),
topTweets: simulatedResults });
}
self.clearResults = function() {
self.resultData(undefined);
}
}
ko.applyBindings(new AppViewModel());
with绑定动态增加移除后代元素依赖于联系的值是null/undefined或非空。
如果需要访问父元素绑定的上下文中的data/functions,可以使用
$parent和root。
关于with的子属性设置的两种写法:
1、写在viewmodel对象中
var viewModel ={
lcon: {
lname: "lfwefw ",
showCon: [
{ name: "s", textInput: "second" },
{ name: "t", textInput: "third" },
{ name: "f", textInput: "first" }]
}
}
2、用创建viewModel函数的写法
function AppViewModel() {
var self = this;
self.resultData({ retrievalDate: new Date(), topTweets:
simulatedResults });
}
与其他没有包括标签一样:
<ul>
<li>Header element</li>
<!-- ko with: outboundFlight -->
...
<!-- /ko -->
<!-- ko with: inboundFlight -->
...
<!-- /ko -->
</ul>
例子:
<html>
<head><title></title>
<script type="text/javascript" src="js/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="js/jquery.tmpl.js"></script>
<script type="text/javascript" src="js/knockout-3.1.0.js"></script>
<script type="text/javascript" src="js/knockout.simpleGrid.js"></script>
<style type="text/css">
</style>
</head>
<body>
<form data-bind="submit: showDetail">
<div>
Your Account:<input type="text" data-bind="value: inputCon" />
<button type="submit">提交信息</button>
</div>
</form>
<div data-bind="visible: hiddenDetail">
<div data-bind="text: inputCon"></div>
<div data-bind="with: lcon">
<div data-bind="text: lname"></div>
<div data-bind="foreach: showCon">
hello:<span data-bind="text: name"></span>
<span data-bind=" text: name"></span>
<br />
</div>
</div>
<button type="submit" data-bind="click: clearCon">隐藏</button>
</div>
<script type="text/javascript">
var viewModel = {
inputCon: ko.observable("@mail"),
showDetail: ko.observable(true),
hiddenDetail: ko.observable(false)
,
lcon: {
lname: "lfwefw ",
showCon: [
{ name: "s", textInput: "second" },
{ name: "t", textInput: "third" },
{ name: "f", textInput: "first" }]
}
};
viewModel.showDetail = function () { viewModel.hiddenDetail(true); }
viewModel.clearCon = function () { viewModel.hiddenDetail(false); }
ko.applyBindings(viewModel);
</script>
</body>
</html>