【问题标题】:Sequentially binding partial views to knockout viewmodel按顺序将部分视图绑定到淘汰视图模型
【发布时间】:2014-09-24 17:06:40
【问题描述】:

我有一个表单,其中包含一个带有网格的主视图和几个(引导)模式表单。模态表单非常复杂,需要很长时间才能下载。表单上的所有内容当前都绑定到单个淘汰视图模型。该视图模型包含(除其他外)下拉项数组和绑定到模态表单元素的可观察属性的子类。

目前,必须先下载整个表单和数据,然后用户才能与页面进行交互。我想将其分解,以便加载按以下方式流动:

  1. 基本的表单元素和css
  2. VM 已实例化
  3. 网格下载数据
  4. grid 绑定到 vm
  5. 用户可以开始交互
  6. 最常用的模态表单元素下载
  7. 模态表单绑定到虚拟机
  8. 对所有模态形式重复 6 和 7

在将网格绑定为部分视图后,我已经能够成功下载模态表单,但现在我收到错误消息“您不能将绑定多次应用于同一元素。”有没有办法将我的部分视图按顺序绑定到同一个视图模型?

这是我将基本页面绑定到虚拟机的代码。请注意,它随后会调用 loadQuoteModal 来加载 Quote Modal 表单。

$(document).ready(function () {
     var vm = new ClientListViewModel();
     ko.applyBindings(vm, document.getElementById("#baseClient"));
     vm.loadQuoteModal();
});

这是我的虚拟机上的 loadQuoteModal。

self.loadQuoteModal = function () {
        var d = $.Deferred();
        var xhr = $.get('/Home/QuoteModalForm');
        xhr.done(function (partialViewResult) {
            $("#LoadQuote").html(partialViewResult);
            ko.applyBindings(this, document.getElementById("#quoteDiv"));
            self.quoteLoaded = true;
        });
        return d;
    }

这是我的页面。

<div id="baseClient">
    <div class="col-md-12" id="clientHeader">
        //Many elements not relevent
    </div>

    <div class="col-md-12" id="clientDiv">
        //Many elements not relevent
    </div>
</div>

<div id="quoteDiv">
</div>

【问题讨论】:

标签: knockout.js


【解决方案1】:

不确定这是否是您要查找的内容,但您可以将不同的 ViewModel 绑定到页面的不同区域。像这样:

<div id="customerPanel"></div>
<div id="productsPanel"></div>

ko.applyBindings(new CustomerViewModel(), document.getElementById("customerPanel"));

ko.applyBindings(new ProductsViewModel(), document.getElementById("productsPanel"));

等等……

【讨论】:

  • 谢谢。我希望避免使用多个 ViewModel 只是因为这意味着此时需要进行更大的重构,但我开始认为这将是必要的。
【解决方案2】:

Ryan Niemeyer 的 good article 讨论了这个问题。他建议做的是创建这个简单的自定义绑定:

ko.bindingHandlers.stopBinding = {
    init: function() {
        return { controlsDescendantBindings: true };
    }
};

ko.virtualElements.allowedBindings.stopBinding = true;

然后在您的标记中,您只需像这样标记第一次不想绑定的元素:

<div id="baseClient">
    <!-- ko stopBinding: true -->
    <div class="col-md-12" id="clientHeader">
        //Many elements not relevent
    </div>
    <!-- /ko -->
    <!-- ko stopBinding: true -->
    <div class="col-md-12" id="clientDiv">
        //Many elements not relevent
    </div>
    <!-- /ko -->
</div>

在您的 ajax 回调中,您只需像以前一样为特定的 DOM 元素运行 applyBindings。

【讨论】:

    【解决方案3】:

    我建议您保留单个 ViewModel,但不要等到所有数据都加载完毕。你在做多个ko.applyBindings的地方,你可以有空的ko.observables,只有在其中设置了数据/子模型后才可见。这些子模型的数据可以在页面加载后异步加载和设置。

    【讨论】:

      【解决方案4】:

      看看this fiddle

          function addDynamicContent() {
              $("#main").append("<div id='dynamic' data-bind='text: fullName'></div>");
              ko.applyBindings(viewModel, $("#dynamic")[0]);
          }
      

      您可以使用它来创建动态加载但仍绑定到一个视图模型的多个局部视图。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-21
        • 2013-05-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多