Knockout 可以將 visible 綁定到DOM 元素上,使得該元素的hidden 或visible 狀態取決於綁定的值。
查看以下knockout的描述,http://knockoutjs.com/documentation/visible-binding.html
When the parameter resolves to a false-like value (e.g., the boolean value false, or the numeric value 0, or null, or undefined),
the binding sets yourElement.style.display to none, causing it to be hidden. This takes priority over any display style you’ve defined using CSS。 當這個參數是一個假值時(舉例來說,布爾值的false , 數值0,或者null,或者undefined),綁定時候設置你的元素的style.display是none,從而使之隱藏起來。這個優先級要高於CSS中定義的. When the parameter resolves to a true-like value (e.g., the boolean value true, or a non-null object or array), the binding removes the yourElement.style.display value,
causing it to become visible。 當這個參數是一個真值時(舉例來說,布爾值是true,或者非空對象與數組),綁定時候移除你display的值,從來顯示出來
當單獨使用knockout框架時,這個visible綁定運行起來相當好,但是,當Knockout和Require兩個框架同時使用時,就出問題了。
先看一個例子,這個例子里有有兩個div,第一次加載頁面時顯示div1,隱藏div2,當按下一步按鈕時,隱藏div1,顯示div2,最后點返回按鈕時,顯示div1,隱藏div2。
ko_visible.htm代碼,
<html>
<head>
<script src="../lib/require/require.js" data-main="ko_visible"></script>
</head>
<body >
<div id="div1" data-bind="visible: showVisibleDiv1">
<p>First name: <span ></span></p>
<p>Last name: <span ></span></p>
<p>Full name: <span ></span></p>
<input type="text" id="inputAddress" /> *
<input type="text" id="inputMoney" /> *
<input type="button" id="btnSave" value="下一步" data-bind="click: SaveClick" />
</div>
<div id="div2" data-bind="visible: showVisibleDiv2">
<table>
<tr>
<td>標題</td><td>內容</td>
</tr>
<tr>
<td></td><td></td>
</tr>
</table>
<input type="button" id="btnNext" value="返回" data-bind="click: NextClick" />
</div>
</body>
</html>
ko_visible.js
require.config({
paths: {
"knockout": "../lib/knockout/knockout-2.3.0",
"jquery": "../lib/jquery/jquery-1.9.1.min"
}
});
require(['jquery', 'knockout'], function ($, ko) {
//數據綁定
$(document).ready(function () {
var viewModel = {
showVisibleDiv1: ko.observable(true),
showVisibleDiv2: ko.observable(false),
SaveClick: function () {
viewModel.showVisibleDiv1(false);
viewModel.showVisibleDiv2(true);
},
NextClick: function () {
viewModel.showVisibleDiv1(true);
viewModel.showVisibleDiv2(false);
}
};
ko.applyBindings(viewModel);
});
});
當運行此頁面時,效果如下圖,div1,div2同時顯示,然后, div2因為visible=false的緣故,又迅速消失。

當頁面中存在多個步驟的div,想一步步執行並控制某些div顯示時, 這個效果是讓人不能接受的.
當頁面初始加載時,因為Require的延遲加載特性(也就是不先加載js,而是先加載元素,異步加載js),當knockout代碼還沒有執行時,元素是沒有被隱藏的,這一點是致命的。
所以,修改的方法有兩個:
1.不使用Require框架。
例子如下:
ko_visible1.htm
<html>
<head>
<script type="text/javascript" src="../lib/knockout/knockout-2.3.0.js"></script>
<script type="text/javascript" src="../lib/jquery/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="ko_visible1.js"></script>
</head>
<body >
<div id="div1" data-bind="visible: showVisibleDiv1">
<p>First name: <span ></span></p>
<p>Last name: <span ></span></p>
<p>Full name: <span ></span></p>
<input type="text" id="inputAddress" /> *
<input type="text" id="inputMoney" /> *
<input type="button" id="btnSave" value="下一步" data-bind="click: SaveClick" />
</div>
<div id="div2" data-bind="visible: showVisibleDiv2">
<table>
<tr>
<td>標題</td><td>內容</td>
</tr>
<tr>
<td></td><td></td>
</tr>
</table>
<input type="button" id="btnNext" value="返回" data-bind="click: NextClick" />
</div>
</body>
</html>
ko_visible1.js
//數據綁定
$(document).ready(function () {
var viewModel = {
showVisibleDiv1: ko.observable(true),
showVisibleDiv2: ko.observable(false),
SaveClick: function () {
viewModel.showVisibleDiv1(false);
viewModel.showVisibleDiv2(true);
},
NextClick: function () {
viewModel.showVisibleDiv1(true);
viewModel.showVisibleDiv2(false);
}
};
ko.applyBindings(viewModel);
});
2.如果必須使用Require框架,那在這種場合,建議不要使用visible,還是使用css的樣式控制。
例子如下:
ko_display.htm
<html>
<head>
<script src="../lib/require/require.js" data-main="ko_display"></script>
</head>
<body >
<div id="div1" data-bind="visible: showVisibleDiv1">
<p>First name: <span ></span></p>
<p>Last name: <span ></span></p>
<p>Full name: <span ></span></p>
<input type="text" id="inputAddress" /> *
<input type="text" id="inputMoney" /> *
<input type="button" id="btnSave" value="下一步" data-bind="click: SaveClick" />
</div>
<div id="div2" style="display:none">
<table>
<tr>
<td>標題</td><td>內容</td>
</tr>
<tr>
<td></td><td></td>
</tr>
</table>
<input type="button" id="btnNext" value="返回" data-bind="click: NextClick" />
</div>
</body>
</html>
ko_display.js
require.config({
paths: {
"knockout": "../lib/knockout/knockout-2.3.0",
"jquery": "../lib/jquery/jquery-1.9.1.min"
}
});
require(['jquery', 'knockout'], function ($, ko) {
//數據綁定
$(document).ready(function () {
var viewModel = {
showVisibleDiv1: ko.observable(true),
SaveClick: function () {
viewModel.showVisibleDiv1(false);
$("#div2").show();
},
NextClick: function () {
viewModel.showVisibleDiv1(true);
$("#div2").hide();
}
};
ko.applyBindings(viewModel);
});
});
以上是本人在項目中遇到的問題總結,如有謬誤之處,還請大家指正!
