Пользовательский ViewComponent с параметром asp-for as

Я хочу обернуть это:

<textarea asp-for="@Model.Content" ...>

в повторно используемый ViewComponent, где свойство будет параметром:

<vc:editor asp-for="@Model.Content" />

Мне удалось передать параметр asp-for as компоненту просмотра:

public class EditorViewComponent : ViewComponent
{
    public IViewComponentResult Invoke(ModelExpression aspFor = null)
    {
        //when debugging, aspFor has correct value
        return View(aspFor);
    }
}

Но я не могу оценить это с точки зрения компонентов. Это не работает:

<!-- ViewComponents/Editor/Default.cshtml -->
@model Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression
<textarea asp-for="@Model" />

Любые идеи?


person Liero    schedule 17.03.2017    source источник
comment
Я думаю, вы смешиваете ViewComponents и TagHelpers. docs.microsoft.com/en-us/aspnet/ core / mvc / views / view-components   -  person Joel Harkes    schedule 17.03.2017
comment
Я просто хочу обернуть свое текстовое поле в viewcomponent, но я не могу передать ModelExpression в текстовое поле. Ваш ответ показывает только, как использовать viewcomponent, но не помогает с передачей ModelExpression в текстовое поле внутри viewcomponent.   -  person Liero    schedule 17.07.2017
comment
Используйте другой класс для вашего приоритета. Нравится modelExpression? Или func ‹T›   -  person Joel Harkes    schedule 18.07.2017
comment
?? Я не уверен, что вы имеете в виду. Какой приоритет? Я уже использую ModelExpresion   -  person Liero    schedule 18.07.2017
comment
*имущество. А, тебе, наверное, придется перекодировать эту часть. Или расширьте помощник тега текстовой области. В любом случае вы, вероятно, захотите создать помощник тега.   -  person Joel Harkes    schedule 19.07.2017


Ответы (2)


Я думаю, вы смешиваете ViewComponents и TagHelpers: https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components

Просмотреть компоненты

Компоненты просмотра вызываются в следующих случаях:

@await Component.InvokeAsync("EditorView", @Model.Property);
// or
<vc:[view-component-name]>

Попробуйте следующий фрагмент:

<vc:editor for="@Model.Content" />

Taghelpers

помощники тегов вызываются только так:

<textarea asp-for="@Model.Content">
person Joel Harkes    schedule 17.03.2017
comment
когда я переименовал параметр aspFor в параметр for, у меня все еще была та же проблема. Я не могу передать его помощнику тега внутри моего ViewComponent - person Liero; 17.03.2017
comment
Я в одной лодке. Какое колдовство и волшебство .NET творится за кулисами, чтобы asp-for работал? Ничего из этого не задокументировано (что я могу найти), и я также хочу создать библиотеку повторно используемых компонентов представления для своего проекта, но, насколько я могу понять, мне нужно вручную установить имя свойства. - person clockwiseq; 05.09.2017
comment
@Keith, должно быть несколько видеороликов, объясняющих, как это работает, в технических демонстрациях Microsoft в прошлом году. Лучше всего проверить исходный код taghelper на GitHub, чтобы вам помочь. - person Joel Harkes; 05.09.2017

Если вы хотите передать ModelExpression в базовый ViewComponent, а затем передать его TagHelper, вы должны сделать это с помощью @TheModelExpression.Model:

<!-- ViewComponents/Editor/Default.cshtml -->
@model Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExpression
<textarea asp-for="@Model.Model" />

Как упоминал @JoelHarkes, в этом конкретном случае более подходящим может быть пользовательский taghelper. В любом случае, я все еще могу отобразить шаблон PartialView ala в TagHelper:

[HtmlTargetElement("editor", Attributes = "asp-for", TagStructure = TagStructure.WithoutEndTag)]
public class EditorTagHelper : TagHelper
{
    private HtmlHelper _htmlHelper;
    private HtmlEncoder _htmlEncoder;

    public EditorTagHelper(IHtmlHelper htmlHelper, HtmlEncoder htmlEncoder)
    {
        _htmlHelper = htmlHelper as HtmlHelper;
        _htmlEncoder = htmlEncoder;
    }

    [HtmlAttributeName("asp-for")]
    public ModelExpression For { get; set; }

    [ViewContext]
    public ViewContext ViewContext
    {
        set => _htmlHelper.Contextualize(value);
    }


    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = null;

        var partialView = await _htmlHelper.PartialAsync("TagHelpers/Editor", For);

        var writer = new StringWriter();
        partialView.WriteTo(writer, _htmlEncoder);

        output.Content.SetHtmlContent(writer.ToString());
    }
}

тогда шаблон .cshtml будет выглядеть точно так же, как в viewcomponent.

person Liero    schedule 30.10.2017