2013-09-26 101 views
2

我有一個ASP.NET MVC 4查看使用KnockoutJs(2.3.0版)加入結合HTML元素。頁面加載得很好,並且任何現有的元素與數據綁定屬性按照預期與KnockoutJs一起工作。問題是,如果我將HTML添加到包含數據綁定的頁面中,該頁面已包含在已綁定的ViewModel中,那麼即使它具有正確的數據綁定屬性,它似乎仍未訂閱。通過Ajax添加的HTML是一個MVC PartialView。阿賈克斯加入後ko.applyBindings不knockoutjs

HTML(開始)

<input type="text" id="FullName" data-bind="value: FullName" />  
<input type="text" id="Units" data-bind="value: Price" /> 
<input type="text" id="Price" data-bind="value: Units" /> 

<div id="AdditionalData"></div> 

KO視圖模型

var ViewModel = function() { 
    var self = this; 
    self.FullName = ko.observable('Bob'); 
    self.Units = ko.observable(@Model.Units); 
    self.Price = ko.observable(@Model.Price); 
    self.SomeValue = ko.observable(); 
    self.CalculatedCost = ko.computed(function() { 
     return self.Units * self.Price; 
    }; 
}; 

ko.applyBindings(new ViewModel()); 

AJAX(.js文件中)

APP.GetPartialView = function() { 
    var _formValues = $("form#MyForm").serializeArray(); 
    var _url = $Url.resolve("~/Shared/_PartialViewName/?" + $.param(_formValues)); 
     function _success(html) { 
      $("#AdditionalData").html(html); 
     }; 

    $.ajax({ 
     url: _url, 
     data: _formValues, 
     cache: false, 
     dataType: "html", 
     success: _success 
    }); 
}; 

MVC控制器:PartialViewResult

[HttpGet] 
public virtual PartialViewResult _PartialViewName(AccountViewModel model) 
{ 
    return PartialView(model); 
} 

MVC PartialView HTML

@model APP.AccountViewModel 

<fieldset> 
    @Html.Hidden("SomeValue", new { data_bind="value: SomeValue" }) 
    <ul> 
     <li> 
      @Html.LabelFor(m => m.FullName) 
      <span data-bind="text: FullName"></span> 
     </li> 
     <li> 
      @Html.LabelFor(m => m.CalculatedCost) 
      <span data-bind="text: CalculatedCost"></span> 
     </li> 
    </ul> 
</fieldset> 

HTML(AJAX調用後)

<input type="text" id="FullName" data-bind="value: FullName" />  
<input type="text" id="Units" data-bind="value: Price" /> 
<input type="text" id="Price" data-bind="value: Units" /> 

<div id="AdditionalData"> 
    <fieldset> 
     <label for="SomeValue" data_bind="value: SomeValue" /> 
     <input type="hidden" id="SomeValue" name="SomeValue" data_bind="value: SomeValue" /> 
     <ul> 
      <li> 
       <label for="FullName" /> 
       <span data-bind="text: FullName"></span> 
      </li> 
      <li> 
       <label for="CalculatedCost" /> 
       <span data-bind="text: CalculatedCost"></span> 
      </li> 
     </ul> 
    </fieldset> 
</div> 

新添加的HTML將不會接收文本計算成本的FullName和ko計算字段將不會寫入同名的可觀察值。

所以,問題是如何告訴Knockout這些元素只是「聚會晚了」,但對已綁定的ViewModel observables具有正確的數據綁定憑據?

更新:我已經更新了上述問題的代碼參考。

+1

爲什麼不乾脆再申請綁定之外的其他地方給他們打電話?一般來說,您應該使用模板並使用ko綁定添加此新標記。 https://github.com/ifandelse/Knockout.js-External-Template-Engine – vittore

+0

@vittore這是我的理解,你只能調用每個DOM負載一次ko.applyBindings()。我已經嘗試過,它會拋出錯誤,指出你不能這樣做多次。關於模板:似乎模板更適合重複數據。上面的例子是我試圖完成的簡化版本,但我確實需要將模型數據從Controller傳遞到PartialView Result,而不太清楚如何以KO模板方式重新構建。看起來,「重新綁定」是所有需要與模板相對應的,但需要採取的建議。 – piercove

回答

1

當淘汰賽進來追加,接下來,innerHTML的所有這些東西走出去的窗口。 問題是你正在以錯誤的方式去做。你想使用基因敲除從這種片段注射逃走。上述

查看型號爲型號:

// This is the model 
var Person = function(data) { 
    var self = this; 
    self.FullName = ko.observable(data.FullName); 
    self.Address = ko.observable(data.Address); 
}; 

// Your viewModel now uses Person to create People: 
var ViewModel = function(){ 
    var self = this; 
    self.People = ko.observableArray() 
    self.addPeople = function(data){ 
     for(i = 0; i < data.length; i++){ 
      self.People.push(new Person(data[i])); 
     } 
    }; 
    self.addSam = function(){ 
     self.People.push(new Person({"FullName" : "Sam", "Address" : "Some address"})); 
    }; 
    self.AddNewPerson = function(data){ 
     self.People.push(new Person(data)); 
    } 
} 

// Now I can create a new instance of VM: 
var vm = new ViewModel(); 
vm.addPeople([{"FullName" : "Jon", "Address" : "Some address"},{"FullName" : "Pete", "Address" : "Some address"}]); 

ko.applyBindings(vm); 

vm.AddNewPerson({"FullName" : "Marry", "Address" : "Some address"}) 

你可以簡單地通過調用內部方法添加新元素或者在你的代碼

<ul data-bind="foreach: People"> 
    <li data-bind="text: FullName"></li> 
</ul> 

<a data-bind="click: addSam" href="#">Click me to add Sam</a> 
+0

我看到你在說什麼,但是我從PartialView中添加的HTML的目的是計算被封裝在一個依賴於主觀測值的ko.computed觀測值中(這兩個觀測值都已經被綁定在這個點上 - 不是最新的HTML元素引用它們)。所以,我不追加一個集合,僅僅是顯示一個帶有可觀察對象(綁定到現有觀察對象的文本)的全新HTML部分,它們都是單個值(又名「1」行數據)......並且以此爲前提使用MVC PartialViews。我會看看是否可以製作像Person這樣的子模型並查看 – piercove