调用部分视图内的视图组件-ASP.NET Core

时间:2019-01-29 11:52:14

标签: razor .net-core partial-views asp.net-core-viewcomponent

我有一个局部视图(“ _FormCustomer”),该视图显示用于创建客户的表单。我也有一个视图组件(“国家列表”),它生成国家/地区的选项列表。现在,我想在表格中显示国家列表。这就是我要做的:

Index.cshtml

<partial name="_FormCustomer" for="@Model._Customer" />

_FormCustomer.cshtml

<select asp-for="@Model.Land" class="form-control">
    @await Component.InvokeAsync("Countrylist");
</select>

CountrylistViewComponent.cs

public async Task<IViewComponentResult> InvokeAsync()
{
    return View(await _countryRepository.GetCountriesAsync());
}

(函数GetCountriesAsync返回国家列表,可以正常工作)

页面/目录/国家列表/default.cshtml

@model List<Country>
@foreach (Country country in Model)
{
    <option value="@country.code">@country.name</option>
}

不幸的是,当我调用局部对话框时,选择框保持为空。当我直接从Index.cshtml调用@await Component.InvokeAsync("Countrylist");时,效果很好。

因此,您似乎无法在部分视图内使用视图组件。这个结论正确吗?还是我做错了什么?

2 个答案:

答案 0 :(得分:0)

我现在已经测试了这种情况,并且可以确认数据加载正常-当视图组件直接包含在页面中或部分视图中包含时。 (我已经在Razor页面上对此进行了测试-但是在使用MVC时它可能会起作用。您没有提到是在使用MVC还是Razor页面。)

您可以尝试以下几种方法来查看加载是否正常:

1)从所有“选择”和“部分”中删除“ for *”属性。这样,您可以先检查数据是否加载,然后再担心绑定到所选项目。 (此外,在提供的代码中,您省略了模型变量-因此无法对其进行注释。)

2)删除最后一个“;”在您的_FormCustomer.cshtml

<select asp-for="@Model.Land" class="form-control">
    @await Component.InvokeAsync("Countrylist")
</select>

请注意,我删除了结尾的“;”在等待语句中。我注意到“;”在选择中被添加为另一个“选项”!

3)我还注意到,即使是很小的语法错误(Intellisense未能识别)也可能导致选择无法加载。进行调试以查看是否实际上正在调用InvokeAsync-在一个较小的语法错误的情况下,甚至没有调用InvokeAsync。

还请记住:

  

“当partial view is instantiated收到时,它会收到一份   父级的ViewData字典。对内部数据的更新   部分视图不会保留到父视图。 ViewData的变化   部分视图返回时,部分视图将丢失。”

答案 1 :(得分:0)

感谢Phantom2018,您发帖后发现了问题。

@ 0:我正在使用Razor页面

@ 1:这没有效果

@ 2:这是我的问题,而不是我的代码中的错字

@ 3:调试器向我显示vie组件被调用,所以

我的实际代码有些不同,如果可以的话,我想预先选择一个国家/地区:

from PyQt5.QtCore import pyqtSignal, QUrl, QUrlQuery
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkReply, QNetworkRequest,QNetworkCookieJar


class NetworkManager(QNetworkAccessManager):
    requestFinished = pyqtSignal(QNetworkReply)

    def __init__(self):
        super().__init__()

    def finished(self, reply):
        super().finished(reply)
        self.requestFinished.emit(reply)


class Request:
    def __init__(self):
        super().__init__()

        self.network_manager = NetworkManager()
        self.network_manager.requestFinished.connect(self.request_finished)

        self.network_manager.setCookieJar(QNetworkCookieJar())

        self.url = ''
        self.cookie_url = ''

    def _read_cookie(self):
        request = QNetworkRequest(QUrl(self.cookie_url))
        request.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded")
        self.network_manager.get(request)

    def _post(self):
        post_data = QUrlQuery()
        post_data.addQueryItem("param1", "value")
        post_data.addQueryItem("param2", "value")

        request = QNetworkRequest(QUrl(self.url))
        request.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded")

         self.network_manager.post(request, post_data.toString(QUrl.FullyEncoded).toUtf8())

    def post_request(self, url, cookie_url):
        self.url = url
        self.cookie_url = cookie_url

        self._read_cookie()

    def request_finished(self, reply: QNetworkReply):
        reply.deleteLater()

        cookies = reply.header(QNetworkRequest.SetCookieHeader)
        if cookies:
            self.network_manager.cookieJar().setCookiesFromUrl(cookies, self.url)

        self._post()

经过一些测试,我找到了解决方案:

<select asp-for="@Model.Country" class="form-control">
    @if (Model == null)
    {
        await Component.InvokeAsync("Countrylist");
    }
    else
    {
        await Component.InvokeAsync("Countrylist", Model.Country);
    }  
</select>

不知道为什么,但是我不得不在等待之前使用<select asp-for="@Model.Country" class="form-control"> @if (Model == null) { @await Component.InvokeAsync("Countrylist"); } else { @await Component.InvokeAsync("Countrylist", Model.Country); } </select>