knockout.js: где сохранить модель представления, если вызов AJAX находится в пользовательском контроле - PullRequest
0 голосов
/ 23 марта 2012

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

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

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

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>

Веб-служба:

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; }
    }
}

1 Ответ

0 голосов
/ 23 марта 2012

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

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

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

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

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

Надежда помогает.Счастливое кодирование

...