首页 文章

两个单独的模型 - 您不能多次将绑定应用于同一元素

提问于
浏览
0

我有一个MVC应用程序,它有一个链接到视图模型的内容页面 . 它运作良好 . 但是只要我将视图模型添加到我的内容页面(在我的布局中生成),我就会收到错误:

您不能多次将绑定应用于同一元素 .

我创建了“Sections”并尝试绑定到该部分,如下所示 .

//在我的布局页面中 .

<div class='liveExample' id="sectionOne">   
    <p>First name: <input data-bind='value: firstName' /></p> 
    <p>Last name: <input data-bind='value: lastName' /></p> 
    <h2>Hello, <span data-bind='text: fullName'> </span>!</h2>  
</div>

//在我的索引(内容)页面中 .

<div class='liveExample' id="sectionTwo">   
    <p>First name: <input data-bind='value: firstName' /></p> 
    <p>Last name: <input data-bind='value: lastName' /></p> 
    <h2>Hello, <span data-bind='text: fullName'> </span>!</h2>  
</div>

和代码:

//在我的_Layout页面中:ko.applyBindings(新的ViewModel1(“Planet”,“Earth”),$(“#sectionOne”)[0]); //这使得Knockout开始工作

//在我的索引页面中:ko.applyBindings(new ViewModel2(“Planet”,“Earth”),$(“#sectionTwo”)[0]); //这使得Knockout开始工作

这是一个jsfiddle

https://jsfiddle.net/4fe2f6mL/1/

我不能创建一个主视图模型,上面的两个模型作为子视图,因为ko.applyBindings在单独的cshtml文件上 .

我怎样才能使这个工作,因为我有一个用于我的布局的视图模型(驱动菜单,登录,注册和导航栏中的“欢迎,用户名”类型的东西)

1 回答

  • 1

    您链接的示例有效,因为数据绑定元素是兄弟 . 如果存在父子结构,则只能使用 ko.applyBindings 轻松地将子项绑定到与父项不同的视图模型 .

    使用部分.cshtml文件和Razor做模板有时会与淘汰赛自己的模板功能冲突......就个人而言,我倾向于只在部分中定义淘汰templates并使用 foreachwith 绑定来获取我的视图进行渲染 .

    脏修复

    现在,一个快速而又脏的修复方法可能是创建一个自定义绑定,禁用DOM树的一部分中的绑定:

    ko.bindingHandlers.stopBinds = {
      init: function() {
        return { controlsDescendantBindings: true }   
      }
    }
    
    ko.virtualElements.allowedBindings.stopBinds = true;
    
    // In your main js you bind the parent
    var parent = document.getElementById("parent");
    ko.applyBindings({ test: "Parent value" }, parent);
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    
    <div id="parent">
        <p data-bind="text: test"></p>
    
        <!-- start of your partial: -->
    
        <!-- ko stopBinds -->
          <div id="child" >
            <p data-bind="text: test"></p>
          </div>  
          <script>
            var child = document.getElementById("child");
            ko.applyBindings({ test: "Child value" }, child);
          </script>
        <!-- /ko -->
      
        <!-- end of your partial -->
    </div>
    

    稍微好一些

    ko.bindingHandlers.stopBinds = {
      init: function() {
        return { controlsDescendantBindings: true }   
      }
    }
    
    ko.virtualElements.allowedBindings.stopBinds = true;
    
    // Expose the main vm
    window.myVM = {
      test: "Parent value",
      childVM: ko.observable(null)
    };
    
    // Bind to document
    $(document).ready(function() {
      ko.applyBindings(window.myVM);
      
      // Check if any callbacks have been registered and run them
      window.callbacks.forEach(function(cb) {
        cb();
      });
    });
    
    <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.2.0/knockout-min.js"></script>
    
    <div id="parent">
        <p data-bind="text: test"></p>
    
        <!-- start of your partial: -->
          <div id="child" data-bind="with: childVM">
            <p data-bind="text: test"></p>
          </div>  
          <script>
              // Register a callback
              window.callbacks = window.callbacks || [];
              window.callbacks.push(function() {
                window.myVM.childVM({ test: "Child value" });
              });
          </script>
        <!-- end of your partial -->
    </div>
    

相关问题