【问题标题】:KnockoutJS bug changing content of html binding (outside knockout) breaks html bindingKnockoutJS bug 更改 html 绑定的内容(外部淘汰)会破坏 html 绑定
【发布时间】:2016-11-23 03:32:44
【问题描述】:

相关,但没有解决问题:KnockoutJS: Using 'html' binding, new elements not binding

如果您有一个元素上的html 绑定,并在剔除和/或剔除视图模型之外更改此html 绑定的内部html,您将无法再控制更改原始html 绑定。请看下面的sn-p

我对保留更改内容的方法(运行原始 javascript/jquery)更感兴趣,并且更愿意理解/修复为什么调用 setdefault() 不会更新绑定

任何文档或链接也会有所帮助

$(document).ready(function(){
  
  var VIEWMODEL = function(){
  	var _ = this;
    
    _.content = ko.observable("<div>content</div>")
    _.asyncoperation = function(){
    	$("#target")[0].innerHTML = "<div>async operation content</div>";
    }
    _.setdefault = function(){
    	_.content("<div>content</div>");
    }
  };
  var vm = new VIEWMODEL();
  
  ko.applyBindings(vm, $("#container")[0]);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="container">
  <div id="target" data-bind="html: content"></div>
  <br/>
  <br/>
  
  <button data-bind="click: asyncoperation">async operation to replace text</button>
  <button data-bind="click: setdefault">set to default</button>
  
</div>

【问题讨论】:

  • 我找不到任何文档/链接来解释为什么会出现这种情况,但这通常是使用淘汰赛的不明智的方法。为什么要在不使用淘汰赛的情况下更新内容?
  • 由于 AB 测试,我只能更改此内容。这两个系统是分开的,我需要根据 A 或 B 更改 html。我宁愿不在窗口上创建我的视图模型来更改 ko.observable 那样

标签: javascript jquery html knockout.js


【解决方案1】:

在 Knockout 中,可观察对象通常不会对实际上不会更改值的更新做出反应。但这可以使用notify extender 进行更改,如下例所示。

另一方面,如果可能,通常最好通过淘汰赛。您可以使用 knockout-postbox 之类的东西来执行此操作。

使用邮箱

_.content = ko.observable("<div>content</div>").subscribeTo("content");
_.asyncoperation = function() {
    ko.postbox.publish("content", "<div>async operation content</div>");
}

http://jsfiddle.net/bLdv296r/

使用通知扩展器

_.content = ko.observable("<div>content</div>").extend({notify:'always'});

$(document).ready(function(){
  
  var VIEWMODEL = function(){
  	var _ = this;
    
    _.content = ko.observable("<div>content</div>").extend({notify:'always'});
    _.asyncoperation = function(){
    	$("#target")[0].innerHTML = "<div>async operation content</div>";
    }
    _.setdefault = function(){
    	_.content("<div>content</div>");
    }
  };
  var vm = new VIEWMODEL();
  
  ko.applyBindings(vm, $("#container")[0]);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="container">
  <div id="target" data-bind="html: content"></div>
  <br/>
  <br/>
  
  <button data-bind="click: asyncoperation">async operation to replace text</button>
  <button data-bind="click: setdefault">set to default</button>
  
</div>

【讨论】:

    【解决方案2】:

    这样的东西会起作用吗?在模型定义之外的 onclick 事件上更新模型。您仍在更新可观察但在模型定义之外。

    这是一个小提琴http://jsfiddle.net/LkqTU/32527/

      $(document).ready(function() {
              ko.applyBindings(mymodel);
              $('#asyncoperation').click(function() {
                  mymodel.content("<div>async operation content</div>");
                  });
    
              });
    

    【讨论】:

    • 理想情况下,没有。我宁愿避免让我的单独系统直接访问视图模型,但如果我找不到其他选项,我会考虑它
    • 我认为这就是答案。如果您不希望第二个系统直接访问视图模型,请创建一个中间设置器函数。
    猜你喜欢
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 2022-10-17
    • 1970-01-01
    • 2015-01-24
    相关资源
    最近更新 更多