【问题标题】:How to update binding or remove earlier binding in knockoutjs如何在 knockoutjs 中更新绑定或删除较早的绑定
【发布时间】:2012-08-14 08:26:44
【问题描述】:

我有以下代码从 ajax 调用中获取数据并与我页面的不同部分绑定。

$.getJSON("api/RedeemProduct", { 'productId': productId }, function (data) {
    categoryViewModel = ko.mapping.fromJS(data[0].WishlistProduct.WishlistCategory);
    ko.applyBindings(categoryViewModel, $('section.intro').get(0));

    activityTypesViewModel = ko.mapping.fromJS(data);
    ko.applyBindings(activityTypesViewModel, $('.categories-gallery .frame').get(0));

    activeActivityViewModel = ko.mapping.fromJS($('.categories-gallery .frame .category.active').data('wishlist-activity'));
    ko.applyBindings(activeActivityViewModel, $('#details-box').get(0));

查看代码的第一行,我正在获取特定产品的数据。下次如果我使用相同的代码绑定不同产品的数据,绑定不会被更新,而是因为调用 ko.applyBindings() 而多次添加相同的产品

我应该怎么做才能删除旧绑定并将新数据与节绑定?

【问题讨论】:

    标签: knockout.js knockout-mapping-plugin


    【解决方案1】:

    停止多次使用ko.applyBindings。我觉得这需要进入标签维基。

    永远不要这样做。

    调用ko.applyBindings 一次(每个元素,如果你是这样做的,但仍然一次)。之后,更新您的视图模型将自动更新绑定的元素。这就是绑定的全部

    【讨论】:

    • 我只在文档加载时调用 ko.applyBindings,现在只从 ajax 数据更新模型,但页面数据仍未更新。
    • 你能发布一些你的代码吗,也许是在小提琴中。 “它没有更新”不足以解决问题
    • 这个问题被问了很多,大概是因为 knockout.js 太难搞清楚/调试了。我想当时的选择是 a) 停止使用 knockout.js,b) 如果你坚持使用 knockout.js,那么就做对。
    • @HamishGrubijan 我想你可以责怪 Knockout,但我认为这不公平。如果这个人浏览了网站上的教程,他就会知道自己做错了。不管一个工具使用起来多么简单,总有一种方法使用不正确。人们拿起它并像锤子一样使用它并不是螺丝刀的反映。
    • Tyrsius,我也是那个人。我浏览了教程,花了一天时间尝试触发某些事件(在一个大型项目中,而不是带有按钮示例的单个标签),然后说搞砸了,而是用 jQuery 中的几行代码来代替 - 手动更新 DOM而不是尝试修改数组内部的 observable 的一部分。我想不出调试淘汰赛库的好方法,因此我不热衷于学习它。 JS/jQuery 的东西——我在浏览器中有一个调试器和一个“REPL”。
    【解决方案2】:

    我找到了解决办法,我得打电话

    ko.mapping.fromJs
    

    并传递需要更新的newdataviewmodel

    ko.mapping.fromJS(data[0].WishlistProduct.WishlistCategory, categoryViewModel);
    

    【讨论】:

      【解决方案3】:

      查看 Knockout.js 官方页面中的 tutorial 来解决这个问题。

      简而言之,您应该只调用一次applyBindings()(对于给定的页面部分),并且在检索更新的数据时,您应该像这样使用新数据更新可观察视图模型

      var updatedCategoryViewModel = ko.mapping.fromJS(data[0].WishlistProduct.WishlistCategory);
      categoryViewModel(updatedCategoryViewModel);
      

      【讨论】:

      • 我已经删除了应用绑定,现在只是更新模型但仍然没有运气
      【解决方案4】:

      希望这对某人有所帮助,Knockout 对我来说是一段旅程,也是一个令人心碎的模特。

      单击按钮时我需要加载或多或少的内容,所以起初我认为这会对我有所帮助,这是我的第一种方法:

      var Task = function(name, description) {
          this.name = ko.observable(name);  
          this.description = ko.observable(description);      
      
      }
      
      var ViewModel = function() {
          var self = this;
          self.tasks = ko.observableArray();
      
          self.clearTask = function(data, event) {
      
                 self.tasks.remove(data);   
      
          };
          self.addTask = function() {
              var task = new Task("new", "");        
              self.tasks.push(task);
          };
          self.addTask2 = function (name, description)
          {
              var task = new Task(name, description);        
              self.tasks.push(task);
          }
      
      };
      var vm = new ViewModel();
      vm.addTask2("Dog Food","description");
      ko.applyBindings(vm);
      
      function ClickedMoreItems()
      {
          vm = new ViewModel()
          vm.addTask2("Dog Food2","description");
          vm.addTask2("Dog Food3","description");    
      
      }
      function ClickedLessItems()
      {
          vm = new ViewModel()
          vm.addTask2("Dog Food4","description");        
      
      }
      

      点击 ClickedMoreItems() 后,什么也没发生。所以我决定在每个函数中再次使用ko.applyBindings(vm);,它有点工作。但是当我点击 ClickedLessItems 时,“Dog Food4”被复制了两次。

      function ClickedMoreItems()
          {
              vm.Clear();
              vm.addTask2("Dog Food2","description");
              vm.addTask2("Dog Food3","description");    
              ko.applyBindings(vm);        
          }
          function ClickedLessItems()
          {
              vm.Clear();
              vm.addTask2("Dog Food4","description");  
              ko.applyBindings(vm);        
          }
      

      所以我决定这样做并让它发挥作用:

      1. 按照 Tyrsius 的建议,在开头使用 ko.applyBindings(vm);
      2. 创建一个清晰的函数

      所以最后的代码是这样的:

      var Task = function(name, description) {
          this.name = ko.observable(name);  
          this.description = ko.observable(description);                
      }
      
      var ViewModel = function() {
          var self = this;
          self.tasks = ko.observableArray();
      
          self.clearTask = function(data, event) {
      
                 self.tasks.remove(data);   
      
          };
          self.addTask = function() {
              var task = new Task("new", "");        
              self.tasks.push(task);
          };
          self.addTask2 = function (name, description)
          {
              var task = new Task(name, description);        
              self.tasks.push(task);
          }
          self.Clear = function()
          {
              self.tasks.removeAll();
          }
      };
      var vm = new ViewModel();
      vm.addTask2("Dog Food","description");
      ko.applyBindings(vm);
      
      function ClickedMoreItems()
      {
          vm.Clear();
          vm.addTask2("Dog Food2","description");
          vm.addTask2("Dog Food3","description");    
      
      }
      function ClickedLessItems()
      {
          vm.Clear();
          vm.addTask2("Dog Food4","description");  
      
      }
      

      你可以看到代码在运行HERE

      【讨论】:

        【解决方案5】:

        要删除绑定,请使用 ko.cleanNode(element)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-22
          • 1970-01-01
          • 2012-03-30
          • 2015-05-27
          • 2013-06-26
          • 1970-01-01
          相关资源
          最近更新 更多