2012-10-11 44 views
3

我有一個函數,使ajax調用獲取itnital數據並將其保存到視圖模型。然後,我將返回的viewmodel(字符串數據)傳遞到另一個函數另一個Ajax調用等。每個功能都綁定到onclick按鈕事件。當我將它放入document.ready中時,我只能將初始視圖模型傳遞給其他函數。我從每個函數獲得的數據是100%正確的。但是,無論何時我綁定視圖模型,它都會覆蓋先前的綁定,並且這些值不成立。我對此很陌生,所以如果我做了非常錯誤的事情,請和我一起裸照。下面是代碼:傳遞knockoutjs視圖模型到多個ajax調用

的JavaScript

< 

script type="text/javascript" language='javascript'> 
     var MyProject = {}; 
     var viewModel; 
     MyProject.viewModel = ""; 
     var invoiceModel; 
     $(document).ready(function InitializeInvoice() { 
        $.ajax({ 
         type: "Post", 
         url: "Default.aspx/InitializeModel", 
         data: {}, 
         contentType: "application/json; charset=utf-8", 
         dataType: "json", 
         async: false, 
         success: initializesinvoice 
        }); 
       function initializesinvoice(msg) { 
        var defaultdata = msg.d.Data; 
        invoiceModel = defaultdata; 
        MyProject.viewModel = ko.mapping.fromJS(invoiceModel); 
        ko.applyBindings(MyProject.viewModel) 
       }; 
      }) 
      function GetVendorInvoiceDefaults() { 
       MyProject.viewModel = JSON.stringify(invoiceModel); 
       var data = '{invoice:' + MyProject.viewModel + '}'; 
       $.ajax({ 
        type: "Post", 
        url: "Default.aspx/GetVendorInvoiceDefaults", 
        data: data, 
        contentType: "application/json; charset=utf-8", 
        dataType: "json", 
        async: false, 
        success: GetVendorInvoiceDefaultsSuccess 
       }); 
      } 
      function GetVendorInvoiceDefaultsSuccess(msg) { 
       var defaultdata = msg.d.Data; 
       invoiceModel = defaultdata; 
       MyProject.viewModel = ko.mapping.fromJS(invoiceModel); 
       ko.applyBindings(MyProject.viewModel) 
      }; 

      function GetVendorCode() { 
       var vendormodel = JSON.stringify(invoiceModel); 
       var data = '{invoice:' + vendormodel + '}'; 
       $.ajax({ 
        type: "Post", 
        url: "Default.aspx/GetVendorCode", 
        data: '{invoice:' + vendormodel + '}', 
        contentType: "application/json; charset=utf-8", 
        dataType: "json", 
        async: false, 
        success: GetVendorCodeSucess 
       }); 
      } 

      function GetVendorCodeSucess(msg) { 
       var defaultdata = msg.d.Data; 
       MyProject.viewModel = ko.mapping.fromJS(defaultdata); 
       ko.applyBindings(MyProject.viewModel) 
      }; 
#HTML# 
    <p> Invoice Description <asp:TextBox ID="txtdesc" runat="server" data-bind="value:InvoiceDescription"> </asp:TextBox></p>  
    <p> Distribution Code <asp:TextBox ID="txtdistcode" runat="server" data-bind="value:DistributionCode"></asp:TextBox></p> 
    <p> Vendor Code <asp:TextBox ID="txtvendor" runat="server" data-bind="value:VendorCode" ></asp:TextBox></p> 
    <p> <button onclick="InitializeInvoice()">InitializeInvoice</button></p> 
    <p><button id="btndefaults" onclick="GetVendorInvoiceDefaults()">GetVendorInvoiceDefaults</button></p> 
    <p><button id="btnvendor" onclick="GetVendorCode()">GetVendorCode</button><p> 
</pre> 

#ASPX file# 
    namespace WebApplication9 
    { 

    public partial class _Default : System.Web.UI.Page 
    { 
     protected void Page_Load(object sender, EventArgs e) 
     { 


     } 

     protected override void OnLoad(EventArgs e) 
     { 
      if (IsPostBack) 
      { 

       clientSideIsPostBack.Value = "Y"; 
      } 

      else 
        clientSideIsPostBack.Value = "N"; 

       base.OnLoad(e); 
     } 

     [WebMethod] 
     public static JsonResult InitializeModel() 
     { 

      var Invoice = new Invoice() { InvoiceNumber = "1235", InvoiceDescription = "Hello World", DistributionCode = "" }; 
      JsonResult r = new JsonResult(); 
      r.Data = Invoice; 
      return r; //serializer.Deserialize(Invoice, typeof(Invoice)) as JsonResult; 
     } 

     [WebMethod] 
     public static JsonResult GetVendorInvoiceDefaults(Invoice invoice) 
     { 
      JavaScriptSerializer serializer = new JavaScriptSerializer(); 
      invoice.DistributionCode = "HELLO WORLD"; 
      JsonResult r = new JsonResult(); 
      r.Data = invoice; 
      return r; 
      //return new JsonResult() { Data = invoice }; 
     } 

     [WebMethod] 
     public static JsonResult GetVendorCode(Invoice invoice) 
     { 
      JavaScriptSerializer serializer = new JavaScriptSerializer(); 
      invoice.VendorCode = "AHM"; 
      JsonResult r = new JsonResult(); 
      r.Data = invoice; 
      return r; 
     } 

    } 


    public class Invoice 
    { 
     private string distributionCode; 
     private string vendorcode; 

     public string InvoiceNumber { get; set; } 
     public string InvoiceDescription { get; set; } 
     public string DistributionCode 
     { 
      get 
      { 
       return distributionCode ?? string.Empty; 
      } 
      set 
      { 
       distributionCode = value; 
      } 
     } 
     public string VendorCode 
     { 
      get 
      { 
       return vendorcode ?? string.Empty; 

      } 
      set 
      { 
       vendorcode = value; 

      } 
     } 

    } 
    } 

回答

3

所以,你永遠不應該在一個以上的方式撥打電話,或一次以上(每格)ko.applyBindings(MyProject.viewModel).

一旦一個視圖模型綁定有已經被應用,它們被應用。 你永遠不會重複這一步!這非常重要。當更新MyProject.viewModel中的值時,綁定會自動更新HTML。這就是整個問題。當您多次撥打applyBindings時,您將創建各種意想不到的行爲。

設置您的viewModel,applyBindings一次,然後讓所有其他代碼正確更新viewmodel。我建議在執行之前在document.ready處理程序中執行此操作,如接線ajaxy的東西。

其次,使用KO映射插件,per the documentation時,您更新這樣整個視圖模型:ko.mapping.fromJS(data, viewModel);調用每次MyProject.viewModel = ko.mapping.fromJS(invoiceModel);將覆蓋您的視圖模型。

這是Knockout的另一個關鍵方面。因爲可觀察值是函數,所以通過傳遞新值作爲參數來更新它們,而不是像正常變量一樣覆蓋它們。

右:

viewModel.observable(newValue)

錯誤:

viewModel.observable = newvalue

+0

謝謝您的意見。什麼解決了我的問題就是在頁面加載時創建該類的全局對象,並且以這種方式,類成員對所有方法都是有效的。但我同意你提出的觀點,都是有道理的。謝謝! –

+3

+1讓我第六次閱讀文檔並最終獲得它。順便說一下,當前版本需要提供一個映射參數:ko.mapping.fromJS(data,{},viewModel); –