2012-03-23 37 views
0

我很努力地理解用戶在頁面上時我在哪裏保留viewmodel。我有幾個用戶控件,使AJAX請求和應用binging在用戶控件中的控件。我正在使用映射插件來填充我的視圖模型。我在頁面上有4-5個用戶控件。我努力將視圖模型保存在內存中,以便它可以檢測到更改並將其發送回服務器。截至目前,我將它們保存在window.Model1屬性中,這不是一個好主意。knockout.js:如果AJAX調用在usercontrol中保存viewmodel的位置

有人可以告訴我什麼是保持viewmodels在內存中的最佳方式,以便我可以檢測到更改?還是說我做的是錯誤的,有更好的方法來處理這種情況。

這裏是所有的代碼。

用戶控件:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ucCustomer.ascx.cs" Inherits="WebApplication2.UserControl.ucCustomer" %> 

<input data-bind="value: FirstName" /><br /> 
<span>FirstName: </span><span data-bind="text: FirstName"></span><br /> 
<input data-bind="value: FirstName" /><br /> 
<span>FirstName: </span><span data-bind="text: LastName"></span><br /> 

<script type="text/javascript"> 

    $.ajax({ 
     type: "POST", 
     url: "ws/GetData.asmx/GetCustomer", 
     cache: false, 
     contentType: "application/json; charset=utf-8", 
     data: "{}", 
     dataType: "json", 
     success: handleHtml, 
     error: ajaxFailed 
    }); 


    function handleHtml(data, status) { 

     var myViewModel = ko.mapping.fromJS(data.d); 
     window.myViewModel = myViewModel; 



     ko.applyBindings(myViewModel); 
    } 

    function ajaxFailed(xmlRequest) { 
     alert(xmlRequest.status + ' \n\r ' + 
       xmlRequest.statusText + '\n\r' + 
       xmlRequest.responseText); 
    } 

</script> 

ASPX頁面:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" 
    CodeBehind="Default.aspx.cs" Inherits="WebApplication2._Default" %> 

<%@ Register Src="UserControl/ucCustomer.ascx" TagName="ucCustomer" TagPrefix="uc1" %> 
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent"> 
    <script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script> 
    <script src="Scripts/knockout.debug.js" type="text/javascript"></script> 
    <script src="Scripts/knockout.mapping-latest.js" type="text/javascript"></script> 
    <script type="text/javascript"> 
     function SendDataBackToServer() { 
      var arrayList = new ArrayList(); 
      arraylist[0] = window.myViewModel; 
      arraylist[1] = window.myViewModel1; 
      arraylist[2] = window.myViewModel2; 

      //Make an AJAX call here and send arrayList back to server 
      return false; 
     } 

    </script> 
</asp:Content> 
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent"> 
    <div id="dvCust"> 
     <uc1:ucCustomer ID="ucCustomer1" runat="server" /> 
    </div> 
    <div> 
     <button title="Send Data Back" onclick="JavaScript: return SendDataBackToServer();"> 
      Send Data Back To Server</button> 
    </div> 
</asp:Content> 

Web服務:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Services; 
using WebApplication2.DataModel; 

namespace WebApplication2.WS 
{ 
    /// <summary> 
    /// Summary description for GetData 
    /// </summary> 
    [WebService(Namespace = "http://tempuri.org/")] 
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
    [System.ComponentModel.ToolboxItem(false)] 
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    [System.Web.Script.Services.ScriptService] 
    public class GetData : System.Web.Services.WebService 
    { 

     [WebMethod] 
     public Customer GetCustomer() 
     { 
      return new Customer 
      { 
       FirstName = "FName", 
       LastName = "LName" 
      }; 
     } 
    } 
} 

客戶型號:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

namespace WebApplication2.DataModel 
{ 
    public class Customer 
    { 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
    } 
} 
+0

看看這篇文章,它幫了我很多:) [使用與asp.net淘汰賽](http://www.codeproject.com/Articles/153735/Using-KnockoutJS-in-your -ASP-NET-應用程序) – Arnstein 2012-10-24 09:05:39

回答

0

不確定您的應用程序的工作方式。它似乎只有使用淘汰賽的輔助任務,而不是應用程序的主要功能。我認爲使用全局命名空間可能是最好的解決方案。

如果您在函數體外創建變量,那麼該變量位於全局範圍內。因此,選擇一個命名空間var myknockoutnamespace = {},然後將你需要的任何結構放入(多視圖模型,靜態類,Konkani代碼實現等...)

我知道這是高層次,但答案其實很簡單。只要您將所有工作都保存在您自己的唯一名稱空間中,使用全局範圍實際上沒有任何問題。

另一個合理的解決方案是jQuery .data() method。有了它,您可以將數據與DOM節點相關聯。您的每個用戶控件都可以擁有一個甚至不需要可見的Dom節點,或者它可以是您綁定到您的視圖模型的節點(也許,從來沒有嘗試過)。離開頁面或刪除Dom元素可以有效地刪除您的名稱空間/視圖模型。這將數據保存在DOM中並且不在全局名稱空間中。您可以使用節點選擇器在任何地方調用變量。 $('#myusercontrolcontainer').data() //returns whatever data us associated to that dom node.

jQuery,在整個插件和jQueryUI中廣泛使用它作爲其數據存儲方法。

希望是幫助。快樂編碼

+0

你是什麼意思,使用淘汰賽的輔助任務?不是KO將數據綁定到元素並跟蹤更改的主要任務嗎? – Asdfg 2012-03-23 02:50:56

+0

我假設,根據您的示例,您正在通過淘汰賽提供小部分應用程序功能。因爲您在頁面呈現後立即運行Ajax語句,並且不會立即顯示任何稍後更新該數據的方式。我真的好奇你爲什麼選擇這樣做。如果數據在加載用戶控件的時候是可知的,爲什麼不使用asp.NET來傳遞這些內容呢? – 2012-03-23 04:33:08

+0

要清楚的是,無論您是在編寫100%knockoutJS應用程序還是僅爲您的應用程序添加小功能,上面的答案仍然適用,我認爲。我正在編寫一個使用全局變量作爲我的名字空間的完整應用程序。每個視圖模型,視圖,控制器等......都住在那個POJO中。 – 2012-03-23 04:38:07

相關問題