Knockout真正強大之處在於繫結機制,通過data-bind
屬性值體現繫結,不僅可以繫結值,還可以繫結事件,甚至可以自定義繫結。
從一個例子看Knockou的繫結機制
假設想給一個button元素變成jQuery UI的button,大致這樣做:
<button id="btn">點我</button>
$('#btn').button( icons: { primary: 'ui-icon-gear' } );
"他山之石,可以攻玉",實際上Knockout可以通過它的繫結機制來借用其它js類庫實現相同的功能。如果能做到以下這樣就好了:
<button data-bind="jqButton: { icons: { primary: 'ui-icon-gear' } }">點我</button>
如果我們想給Knockout增加自定義繫結,必須通過ko.bindingHandlers
屬性。
<button data-bind="click: sayHello, jqButton: { icons: { primary: 'ui-icon-gear' } }">點我</button>
@section scripts{<script src="~/Scripts/knockout-3.2.0.js"></script>
<script type="text/javascript">
ko.bindingHandlers.jqButton = {init: function (element, valueAccessor) {var options = valueAccessor() || {};$(element).button(options);ko.utils.domNodeDisposal.addDisposeCallback(element, function () {$(element).button("destroy");
});}};var vm = {sayHello: function () {alert("hello");
}};ko.applyBindings(vm);</script>}
以上,通過ko.bindingHandlers
,增加了一個名稱為jqButton
的繫結。
到這裡,有必要了解一下Knockout的繫結機制了。
ko.bindingHandlers.myCustomBinding = {init: function(element, valueAccessor, allBindingsAccessor, data, context) {},update: function(element, valueAccessor, allBindingsAccessor, data, context) {}};
init
update
函式只在View Model中,具有observable的成員值發生改變的時候被執行。
init
和update
包含5個引數:
○ element
表示實施繫結的DOM元素
○ valueAccessor
表示傳值給繫結機制的函式,該函式可能是View Model中具有Observable的成員,也有可能是json物件。
○ allBindingsAccessor
用來獲取運用在同一DOM元素上的所有繫結
○ data
用來獲取View Model
○ context
繫結的上下文,包括$data, $parent, $parents, $root等屬性
更新View Model的時候讓DOM元素閃一下
繫結無非就是關乎View Model和Dom元素,現在,當View Model中具有Obserable的成員值反生變化的時候,讓DOM元素閃一下(實際上就是讓DOM元素先隱藏再慢慢顯現)。根據繫結機制,肯定要自定義update
函式。
@{ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}<h2>Index</h2><style type="text/css">
.main {background-color: #CCC;}</style><div class="main" data-bind="flash: name"><span data-bind="text: name"></span>
</div><hr/><input data-bind="value: name"/>
@section scripts{<script src="~/Scripts/knockout-3.2.0.js"></script>
<script type="text/javascript">
ko.bindingHandlers.flash = {update: function(element, valueAccessor) {ko.utils.unwrapObservable(valueAccessor());$(element).hide().fadeIn(500);}};var vm = {name: ko.observable("darren")
};ko.applyBindings(vm);</script>}
每當input值發生變化,div區域總會閃一下。
給現有的繫結再套上一層繫結
比如說,Knockout已經有了一個名稱為text的繫結,當View Model中具有Obserable的成員值發生改變,繫結text的DOM元素值也會隨之發生變化。如果我們想讓text值發生變化的時候閃動一下,該如何做呢?
<input data-bind="value: name"/>
<hr/><span data-bind="fadeText: name"></span>
@section scripts{<script src="~/Scripts/knockout-3.2.0.js"></script>
<script type="text/javascript">
ko.bindingHandlers.fadeText = {update: function(element, valueAccessor) {$(element).hide();ko.bindingHandlers.text.update(element, valueAccessor);$(element).fadeIn(500);}};var vm = {name: ko.observable("darren")
};ko.applyBindings(vm);</script>}
以上,當input值發生變化的時候,span的值隨之閃動並變化。