2012-03-23 3 views
0

Я изо всех сил пытаюсь понять, где я могу держать viewmodel, пока пользователь находится на странице. У меня есть несколько usercontrols, которые делают запрос AJAX и применяют binging к элементам управления в usercontrol. Я использую плагин отображения для заполнения моей модели просмотра. У меня есть 4-5 пользовательских элементов управления на странице. Я изо всех сил пытаюсь сохранить модели просмотра в памяти, чтобы он мог обнаружить изменения и отправить обратно на сервер. На данный момент я сохраняю их в свойстве window.Model1, что не является хорошей идеей.knockout.js: где сохранить viewmodel, если вызов AJAX находится в usercontrol

Может кто-нибудь, пожалуйста, скажите мне, что является лучшим способом сохранить модели просмотра в памяти, чтобы я мог обнаружить изменения? Или это то, что я делаю это неправильно неправильно, и есть лучший способ справиться с таким сценарием.

Вот код всего этого.

UserControl:

<%@ 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 Service:

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

ответ

0

Не знаете, как работает ваше приложение. Кажется, что вы используете только нокаут для второстепенных задач, а не основной функции приложения. Я думаю, что использование глобального пространства имен, вероятно, является лучшим решением.

Если вы создаете переменную вне тела функции, то эта переменная находится в глобальной области. Итак, выберите пространство имен var myknockoutnamespace = {}, а затем разместите любую структуру, в которой вы нуждаетесь, (модель множественного просмотра, статические классы, реализация кода Konkani и т. Д.)

Я знаю, что это высокий уровень, но ответ на самом деле так прост. Нет ничего плохого в использовании глобальной области действия, если вы сохраняете всю свою работу в своем собственном уникальном пространстве имен.

Другим разумным решением будет jQuery .data() method. С его помощью вы можете связать данные с узлом DOM. Каждый из ваших пользовательских элементов управления может владеть узлом Dom, который даже не должен быть видимым, или это может быть узел, который вы привязываете к своей модели представления (возможно, никогда не пробовал это сам). Выход из страницы или удаление элемента Dom эффективно удаляет вашу модель пространства имен/представлений. Это позволяет хранить данные внутри DOM и из глобального пространства имен. Вы можете вызвать переменную где угодно, используя селектор узлов. $('#myusercontrolcontainer').data() //returns whatever data us associated to that dom node.

jQuery использует этот экстенсивно во всех плагинах и jQueryUI в качестве метода хранения данных.

Надежды помогают. Happy Code

+0

Что вы подразумеваете, используя нокаут для вторичных задач? не является ли основной задачей KO связывать данные с элементами и отслеживать изменения? – Asdfg

+0

Я предполагал, исходя из вашего примера, что вы выполняете небольшие функции своих приложений через нокаут. так как вы запускаете инструкции Ajax, как только страница отображается, и не сразу видно, каким образом обновить эти данные позже. Я действительно задавался вопросом, почему вы решили сделать это таким образом. Если данные известны в момент загрузки пользовательского элемента управления, почему бы просто не использовать asp.NET для доставки этого контента? –

+0

Чтобы быть ясным, независимо от того, пишете ли вы 100% -ное приложение для нокаута или просто добавляете небольшую функциональность в свое приложение, ответ выше все еще применяется, я думаю. Я пишу полное приложение, используя глобальное var как мое пространство имен. Каждая модель, просмотр, контроллер и т. Д. Все живут внутри одного POJO. –

Смежные вопросы