Knockuot js 似乎只考慮過怎么綁定(ko.applyBindings()),卻沒考慮過怎么去除綁定,當修改了DOM內容,需要重新綁定時,發現似乎無能為力。
一、解決辦法
這里有一個重新綁定的方法,就是使用ko.cleanNode(<YOUR DOM NODE>),然后再使用ko.applyBindings()重新綁定就可以了。
1、VIEW模型
- <h3>3、更改綁定</h3>
- <div id="divSample3">
- 你叫啥?<span id='span3' data-bind='text: name'></span><br/>
- <a href="javascript:void(0)" onclick="updateBingding()">我問的是別名!</a>
- </div>
2、VIEW-MODEL
- <script type="text/javascript">
- var viewModel = function () {
- this.name = ko.observable("張三");
- this.aliasName = ko.observable("三兒");
- };
- //var myModel = new viewModel();
- ko.applyBindings(new viewModel(),document.getElementById('divSample3'));
- var viewModel2 = function () {
- this.name = ko.observable("張三");
- this.aliasName = ko.observable("三兒");
- };
- //更改綁定
- function updateBingding(){
- //$("#span3").attr("data-bind", "text: aliasName"); //使用jQuery
- var span3 = document.getElementById('span3'); //不使用jQuery
- span3.setAttribute("data-bind", "text:aliasName");
- ko.cleanNode(span3);
- ko.applyBindings( new viewModel2(), span3);
- }
- </script>
二、問題
1、但是據說這樣可能存在問題,問題之一是與DOM相關的事件綁定是沒法去除的。
這里提供一個外國哥們使用的方法:
- <script lang="javascript">
- ko.unapplyBindings = function ($node, remove) {
- // unbind events
- $node.find("*").each(function(){
- $(this).unbind();
- });
- // Remove KO subscriptions and references
- if(remove) {
- ko.removeNode($node[0]);
- } else {
- ko.cleanNode($node[0]);
- }
- };
- </script>
這個方法使用jQuery方法在取消綁定前,去除綁定的事件,然后再清除緩存的綁定配置,同時具有一定的通用性。
但這個方法應只對jQuery的事件綁定有效,如果使用其他方式綁定的事件,可能去除不徹底。
2、建議盡量使用if或with綁定來控制,使用下面的形式來操作,靈活性肯定不如直接使用JavaScript操作方便。
<!-- ko if: editortype == 'checkbox' -->\
...
<!-- /ko -->\
三、增加和移除綁定
增加綁定即動態增加一個DOM節點,然后再綁定該DOM節點。移除綁定即將DOM節點原有的綁定給去除,不讓綁定操作再生效。
1、增加綁定
VIEW模型:
- <h3>1、動態添加綁定</h3>
- <div id="divSample1">
- <a href="javascript:void(0)" onclick="add_Binding()">添加綁定</a>
- </div>
VM模型:
- <script type="text/javascript">
- var viewModel = function () {
- };
- var myModel = new viewModel();
- //添加綁定
- function add_Binding(){
- //viewModel添加屬性
- myModel.des = ko.observable("this is a demo");
- //添加綁定元素
- var html = "<span id='add_banding' data-bind='html: des'></span>";
- document.body.innerHTML = document.body.innerHTML + html;
- var add = document.getElementById("add_banding");
- ko.applyBindings(myModel, add);
- }
- </script>
2、去除綁定
VIEW模型:
- <h3>2、移除綁定</h3>
- <div id="divSample2">
- 原始值:<span id='span1' data-bind='text: des'></span><br/>
- 對照值:<span id='span2' data-bind='text: des'></span><br/>
- <a href="javascript:void(0)" onclick="changeModelValue()">改變model屬性值</a>
- <a href="javascript:void(0)" onclick="removeBingding()">去除"對照值"的綁定</a>
- </div>
VM模型:
- <script type="text/javascript">
- var viewModel = function () {
- this.des = ko.observable("this is a demo");
- };
- var myModel = new viewModel();
- ko.applyBindings(myModel, document.getElementById("divSample2"));
- //改變des值
- function changeModelValue(){
- myModel.des(new Date().valueOf());
- }
- //移除綁定
- function removeBingding(){
- var span2 = document.getElementById("span2");
- alert(span2.getAttribute('data-bind'));
- span2.setAttribute("data-bind", "");
- alert(span2.getAttribute('data-bind'));
- ko.cleanNode(span2);
- ko.applyBindings(myModel, span2);
- }
- </script>
說明:此例參照了網上一位兄弟的示例,其思路比較清晰,但其提供的示例並沒有真正解決多次綁定的問題,向這位兄弟表示感謝。
參考:
