Knockout.js 击出JS使用html绑定保持原始html

Knockout.js 击出JS使用html绑定保持原始html,knockout.js,Knockout.js,我的任务是在用户执行某些操作(如搜索、筛选等)时替换页面上的一堆HTML。HTML是通过ajax请求的。我已经用Jquery实现了它,但是现在他们希望用击倒JS。所以我昨天开始学习它,并以这个简单的代码示例结束 HTML 初始标题 更新页面 JS: (函数($,ko){ var viewModel={ header:ko.observable()//最初为空 }; 应用绑定(视图模型); $('body')。在('click','submitButton',updatePage)上 函数upd

我的任务是在用户执行某些操作(如搜索、筛选等)时替换页面上的一堆HTML。HTML是通过ajax请求的。我已经用Jquery实现了它,但是现在他们希望用击倒JS。所以我昨天开始学习它,并以这个简单的代码示例结束

HTML

初始标题
更新页面
JS:

(函数($,ko){
var viewModel={
header:ko.observable()//最初为空
};
应用绑定(视图模型);
$('body')。在('click','submitButton',updatePage)上
函数updatePage(){
viewModel.header(“新标题”);
}
})(jQuery,ko);
但是当我加载它时,KO会删除原来的h1(因为它没有绑定)。我想标题是相同的,直到它是通过按钮更新

我发现了这个例子,它得到了原始值:
但是它只适用于“值”绑定,而我无法让它适用于“html”绑定。

创建一个自定义绑定,它本质上是一个围绕
html
绑定的包装器,用于保存初始内容。您需要提供一个可观察的值来保存旧值

ko.bindingHandlers.savehtml = {
  init: function(element, valueAccessor) {
    const [currentValue, oldValue] = ko.utils.unwrapObservable(valueAccessor());
    oldValue(element.innerHTML); // save the old content

    // forward the arguments to html init in the expected format
    const args = [...arguments];
    args.splice(1, 1, () => currentValue); // valueAccessor
    return ko.bindingHandlers.html.init.apply(this, args);
  },
  update: function(element, valueAccessor) {
    const [currentValue] = ko.utils.unwrapObservable(valueAccessor());
    const args = [...arguments];
    args.splice(1, 1, () => currentValue); // valueAccessor
    return ko.bindingHandlers.html.update.apply(this, args);
  }
};
用法:

<div data-bind="savehtml: [header, oldHeader]">
  <h1>Initial header</h1>
</div>

您的意思是,
标题的值实际上不是“初始空白”,而是“初始标题”。为什么不
标题:ko.observable('Initial header')
,那么?因为在真正的senario中,它不是静态文本。它是从服务器生成的@更准确地说,它甚至更复杂,因为它不仅仅是一个“Header”属性。它是多个服务器端属性和html元素的组合。我只是简单地说了一下。没有理由haim770的建议不起作用。只要在实际数据从服务器到达后用新值更新可观测值即可。observables和数据绑定背后的整个概念是DOM自动更新以反映对您的数据所做的更改,因此请利用这些更改并根据需要更改您的数据。我正在研究自定义绑定,但与您在此处编写的内容相比,我有点偏离:)我检查了您的演示,它在加载时将标题更改为“hello world”。目标是在我调用viewModel.header(“新头”)之前,头不能更改,所以在为头设置新值之前不要修改。本质上是延迟绑定,直到发生更改。
ko.bindingHandlers.savehtml = {
  init: function(element, valueAccessor) {
    const [currentValue, oldValue] = ko.utils.unwrapObservable(valueAccessor());
    oldValue(element.innerHTML); // save the old content

    // forward the arguments to html init in the expected format
    const args = [...arguments];
    args.splice(1, 1, () => currentValue); // valueAccessor
    return ko.bindingHandlers.html.init.apply(this, args);
  },
  update: function(element, valueAccessor) {
    const [currentValue] = ko.utils.unwrapObservable(valueAccessor());
    const args = [...arguments];
    args.splice(1, 1, () => currentValue); // valueAccessor
    return ko.bindingHandlers.html.update.apply(this, args);
  }
};
<div data-bind="savehtml: [header, oldHeader]">
  <h1>Initial header</h1>
</div>
ko.bindingHandlers.deferredhtml = {
  init: function(element, valueAccessor) {
    const html = valueAccessor();
    if (ko.isSubscribable(html)) {
        html.subscribe(h => ko.utils.setHtml(element, h))
          .disposeWhenNodeIsRemoved(element);
    }
    return { controlsDescendantBindings: true };
  }
};