постепенно обновляется модель в asp.net mvc - PullRequest
2 голосов
/ 17 января 2012

У меня длинный дБ сетевой вызов, и я хочу заполнить свою модель кусками.Мы говорим об asp.net MVC.У меня есть смутное представление о том, что каждый раз, когда появляется новый чанк, я должен запускать модель. Привязать (), но я не знаю, как выполнить подключение между

a) службой, которая предоставляет данные вчанки - это реализовано с использованием шаблона событий - каждый раз, когда доступен новый чанк, событие запускается, но какое событие?Он должен содержать ссылку на модель?

b) данные, которые будут привязаны к модели (я полагаю, это должна быть не привязка (), а дополнение к некоторой коллекции)

c) если на этапах a и b все в порядке, изменения будут переданы в представление без дальнейших действий?

Ответы [ 2 ]

3 голосов
/ 17 января 2012

Вы можете использовать длинный опрос со скрытым iframe и частичной кодировкой передачи с сервера, который будет выплевывать теги <script> по мере поступления данных.В этом теге сценария вы можете вызывать пользовательскую функцию JavaScript обратного вызова, которая позаботится о форматировании результатов.


ОБНОВЛЕНИЕ:

В соответствии с запросом в разделе комментариев, здесь приведен пример реализацииметод длинного опроса с использованием скрытого фрейма.

Предположим, у вас есть какая-то модель:

public class MyViewModel
{
    public string Foo { get; set; }
}

и у вас есть служба, которая возвращает эту модель в чанках и уведомляет вызывающую сторону, что чанк доступен с помощью событий:

public class MyService
{
    public void GetModels(Action<MyViewModel, object> onModelAvailable, object state, Action onComplete)
    {
        Task.Factory.StartNew(x =>
        {
            try
            {
                for (int i = 0; i < 10; i++)
                {
                    onModelAvailable(new MyViewModel
                    {
                        Foo = "foo " + i
                    }, x);
                    Thread.Sleep(1000);
                }
            }
            finally
            {
                onComplete();
            }
        }, state);
    }
}

Теперь у нас может быть следующий контроллер:

public class HomeController : AsyncController
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult LongPoll()
    {
        var service = new MyService();
        return new MyActionResult(service);
    }
}

и следующий вид:

<script type="text/javascript">
    // we define a callback function which will be invoked
    // when a chunk is available from the server
    var callback = function (model) {
        // the model variable passed here will represent the chunk
        $($('<div/>', {
            html: model.Foo
        })).appendTo('#result');
    };
</script>

<iframe style="display:none;" src="@Url.Action("longpoll")"></iframe>
<div id="result"></div>

Теперь последняя часть курса - это реализация пользовательскогорезультат действия, которое выполнит фрагментарный перевод:

public class MyActionResult : ActionResult
{
    private readonly MyService _service;
    public MyActionResult(MyService service)
    {
        _service = service;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        var response = context.HttpContext.Response;
        response.BufferOutput = true;
        response.ContentType = "text/html";
        var wait = new ManualResetEvent(false);
        _service.GetModels((model, state) =>
        {
            var httpResponse = (HttpResponseBase)state;
            httpResponse.BufferOutput = true;
            httpResponse.ContentType = "text/html";
            var serializer = new JavaScriptSerializer();
            var script = string.Format(
                "<script type=\"text/javascript\">window.parent.callback({0});</script>",
                serializer.Serialize(model)
            );
            httpResponse.Write(script);
            httpResponse.Flush();
        },
        response,
        () =>
        {
            wait.Set();
        });
        wait.WaitOne();
    }
}
1 голос
/ 17 января 2012

Самое простое решение - использовать опрос, просто несколько ajax-вызовов каждые n-секунд, чтобы проверить, доступны ли новые данные.Недостатки этого подхода: задержка, загрузка сервера.Преимущества: достаточно прост в реализации.Лучшее, но гораздо более сложное решение - это использовать что-то вроде длинного опроса, веб-сокетов и т. Д. Если эта функция того стоит, взгляните на Signal-R , который является асинхронной сигнализациейбиблиотека для ASP.NET, помогающая создавать многопользовательские интерактивные веб-приложения в реальном времени.Добавить его в веб-приложение ASP.NET MVC 3 очень просто.Это хорошее введение в библиотеку: Асинхронные масштабируемые веб-приложения с постоянными и работающими в реальном времени соединениями с SignalR

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...