【问题标题】:ko.cleanNode removes the jQuery .on("focusout") eventko.cleanNode 移除 jQuery .on("focusout") 事件
【发布时间】:2018-05-03 10:47:22
【问题描述】:

我正在使用 Knockout JS 应用程序。这里我在使用 ko.cleanNode(node) 时遇到问题,它会删除 focusout 客户端事件。即,在调用 cleanNode 方法之前 focusOut 在文本框上正常工作。之后 focusOut 事件不会触发。我检查了许多堆栈溢出问题,我只找到了这个删除的原因,没有任何替代解决方案。这是我的代码。

$("#btn").click(function() {
  viewModel = {
    nValue: ko.observable(10)
  }
  ko.cleanNode(document.getElementById("txt"));
  ko.applyBindings(viewModel, document.getElementById("txt"));
});
ko.applyBindings({
  nValue: ko.observable(100)
});
$("#txt").on("focusout", function() {
  alert("focusOut");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<input type="text" id="txt" data-bind="value: nValue" />
<input type="button" id="btn" value="cleannode" />

【问题讨论】:

    标签: javascript jquery knockout.js knockout-3.0


    【解决方案1】:

    来自disposal logic 上的 Knockout 文档:

    删除元素时,Knockout 会运行逻辑来清除与该元素关联的所有数据。作为此逻辑的一部分,如果页面中加载了 jQuery,则Knockout 会调用 jQuery 的 cleanData 方法。在高级方案中,您可能希望阻止或自定义如何在您的应用程序中删除此数据。 Knockout 公开了一个函数ko.utils.domNodeDisposal.cleanExternalData(node),可以重写该函数以支持自定义逻辑。例如,为了防止 cleanData 被调用,可以使用一个空函数来替换标准的cleanExternalData 实现

    因此,请覆盖文档中提到的cleanExternalData

    ko.utils.domNodeDisposal.cleanExternalData = function () {
        // Do nothing. Now any jQuery data associated with elements will
        // not be cleaned up when the elements are removed from the DOM.
    };
    
    $("#btn").click(function() {
      viewModel = {
        nValue: ko.observable(10)
      }
      ko.cleanNode(document.getElementById("txt"));
      ko.applyBindings(viewModel, document.getElementById("txt"));
    });
    
    ko.applyBindings({
      nValue: ko.observable(100)
    });
    
    $("#txt").on("focusout", function() {
      alert("focusOut");
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
    <input type="text" id="txt" data-bind="value: nValue" />
    <input type="button" id="btn" value="cleannode" />

    查看您的代码,如果您的意图只是在单击时更新视图模型的observable 并添加focusOut 事件处理程序,则您根本不需要cleanNodeapplyBindings() 或使用jquery。您可以像这样使用 knokcout 的 clickevent 绑定:

    var viewModel = function() {
      var self = this;
    
      self.nValue = ko.observable(100);
    
      self.increment = function() {
        self.nValue(self.nValue() + 1);
      }
    
      self.focusOut = function() {
        alert("Focus Out");
      }
    };
    
    ko.applyBindings(new viewModel());
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
    <input type="text" id="txt" data-bind="value: nValue, event: { focusout: focusOut }" />
    <input type="button" id="btn" value="increment" data-bind="click: increment" />

    【讨论】:

    • 很好的答案。解决直接问题,并提供更彻底的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多