ViewComponents не являются асинхронными

Я пытаюсь использовать функцию ViewComponents.InvokeAsync(), но почему-то это совсем не асинхронно. Он ожидает рендеринга кода компонента. http://docs.asp.net/en/latest/mvc/views/view-components.html

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

Я думал, что метод ViewComponent.InvokeAsync() будет рендериться асинхронно по отношению к главной странице. Но это не так. Для этого нам нужно использовать AJAX, как описано здесь .


person Jash    schedule 16.03.2016    source источник
comment
Когда вы говорите: «Оно ждет», что вы имеете в виду? То есть, что это значит?   -  person Shaun Luttin    schedule 16.03.2016
comment
Страница отображается только тогда, когда отображается компонент. Я ожидаю, что страница завершит рендеринг, а затем компонент должен отображаться асинхронно. Кроме того, я хотел бы иметь счетчик (gif), который находится на месте для компонента, пока он не будет отображаться.   -  person Jash    schedule 16.03.2016


Ответы (1)


Асинхронизация на стороне сервера не является асинхронностью на стороне клиента

Асинхронизация на стороне сервера не выполняет частичный рендеринг страницы в веб-браузере. Следующий код будет блокироваться до тех пор, пока GetItemsAsync не вернется.

public async Task<IViewComponentResult> InvokeAsync()
{
    var items = await GetItemsAsync();
    return View(items);
}

И этот код будет блокироваться до тех пор, пока itemsTask не завершится.

public async Task<IViewComponentResult> InvokeAsync()
{
    var itemsTask = GetItemsAsync(maxPriority, isDone);

    // We can do some other work here,
    // while the itemsTask is still running.

    var items = await itemsTask;
    return View(items);
}

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

Компонент просмотра AJAX

Чтобы частично отобразить страницу в веб-браузере, нам нужно использовать AJAX на стороне клиента. В следующем примере мы используем AJAX для вызова /Home/GetHelloWorld и рендеринга в файле body.

~/HelloWorldViewComponent.cs

public class HelloWorldViewComponent : ViewComponent
{
    public IViewComponentResult Invoke()
    {
        var model = new string[]
        {
            "Hello", "from", "the", "view", "component."  
        };

        return View("Default", model);
    }     
}

~/HomeController.cs

public class HomeController : Controller
{
    public IActionResult GetHelloWorld()
    {
        return ViewComponent("HelloWorld");
    }
}

~/Views/Shared/Components/HelloWorld/Default.cshtml

@model string[]

<ul>
    @foreach(var item in Model)
    {
        <li>@item</li>
    }
</ul>

~/wwwroot/index.html

<body>
<script src="js/jquery.min.js"></script>
<script>
    $.get("home/GetHelloWorld", function(data) {
        $("body").html(data);
    });
</script>
</body>

локальный: 5000/index.html

Неупорядоченный список, отображающий массив строк.

person Shaun Luttin    schedule 16.03.2016
comment
Привет, Шон, я знаю, что делает асинхронность в C#. В приведенном выше коде нормально, что рендеринг компонента будет заблокирован. Но я ищу, чтобы сначала отображалась остальная часть страницы, а затем компонент. Я думал, что смогу добиться этого с помощью @await component.InvokeAsync(). Пожалуйста, поправьте меня здесь - person Jash; 16.03.2016
comment
Ага. Ты не можешь сделать это. @await все еще на стороне сервера, а не на стороне клиента. Думайте об этом как о await в коде C#. Это просто означает, что мы можем делать другие вещи на сервере между запуском задачи и ожиданием ее завершения. С клиентом вообще не разговаривает. - person Shaun Luttin; 16.03.2016
comment
Ладно, неправильно понял ViewComponent.InvokeAsync. Итак, могу ли я вызывать компоненты с помощью AJAX? любые образцы действительно помогут. Я пытаюсь добиться следующего: у меня есть компонент представления, который я хочу использовать на своей странице XYZ, но я хочу, чтобы этот компонент представления отображался асинхронно. - person Jash; 16.03.2016
comment
Да. Похоже, что можно использовать компонент представления с помощью AJAX. Например. stackoverflow.com/a/32628302/1108891 - person Shaun Luttin; 16.03.2016
comment
Спасибо, это помогает. - person Jash; 16.03.2016
comment
Не могли бы вы использовать контроллер представления для отправки формы, когда пользователь нажимает кнопку «Отправить», он вызывает контроллер, который возвращает контроллер представления, таким образом, вам не нужно обновлять всю страницу???? - person conterio; 18.05.2016
comment
Должен ли контроллер возвращать IViewComponentResult вместо IActionResult? - person Shadi Namrouti; 08.01.2017