0

我有自己的 Accordion 纯代码组件

这是我的观点,我有可以加载的中继器list of article sections。每个文章部分都有list of articles. 因此,我想归档每个文章部分都有自己的手风琴,其中将包含articles. 这就是为什么我有它repeater

<div class="box box-primary">
    <dot:Repeater DataSource="{{value: AccordionList}}">
        <ItemTemplate>
            <coc:Accordion DataSource="{{value: Articles}}"></coc:Accordion>
        </ItemTemplate>
    </dot:Repeater>       
</div>

Accordion 纯代码组件。DataSource即使我清楚地看到,My也始终为 null,其中AccordionList包含List of Articles永远不会为 null,但永远不会传递到 my 的DataSource. 当我将类型更改AccordionListArticleListDTO并将其直接传递给我的Accordion组件时,它运行良好,但这不是我想要的。

public class Accordion : HtmlGenericControl
{
    public Accordion() : base("div")
    {
    }
    public static readonly DotvvmProperty DataSourceProperty;
    static Accordion()
    {
           DataSourceProperty = DotvvmProperty.Register<List<ArticleListDTO>, Accordion>(c=>c.DataSource); 
    }
    //DataSource is always null
    public List<ArticleListDTO> DataSource
    {
        get => (List<ArticleListDTO>)GetValue(DataSourceProperty);
        set => SetValue(DataSourceProperty, value);
    } 

    protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context)
    {
        Attributes.Add("class", "accordion");

        base.AddAttributesToRender(writer, context);
    }

    public void DataBind(IDotvvmRequestContext context)
    {
        Children.Clear();
        foreach (var item in DataSource)
        {
            DataBindItem(this, item, context);
        }
    }....etc

视图模型

public List<ArticleSectionListDTO> AccordionList { get; set; } = new List<ArticleSectionListDTO>();
public List<ArticleSectionListDTO> AccordionListUnsorted { get; set; } = new List<ArticleSectionListDTO>();

protected override void OnItemLoading()
{
    AccordionListUnsorted = Task.Run(() => articleSectionFacade.GetAllNotModifiedArticleSections()).Result;

    AccordionList = Task.Run(() => articleSectionFacade.CreateTree(AccordionListUnsorted, null)).Result.ToList();
}

DTO - 我删除了其余属性以使其清楚

public class ArticleListDTO
{
    public string Name { get; set; }

    public int? ParentArticleId { get; set; }
    public bool HasCategories => AssignedToArticle?.Count > 0;
    public List<ArticleListDTO> AssignedToArticle { get; set; }
    //Can contain sub articles
    public List<ArticleListDTO> Articles { get; set; } = new List<ArticleListDTO>();
}

public class ArticleSectionListDTO : ListDTO
{
    public string Name { get; set; }

    public int? ParentArticleSectionId { get; set; }
    public bool HasCategories => AssignedToMenuItem?.Count > 0;
    public List<ArticleSectionListDTO> AssignedToMenuItem { get; set; }
    public List<ArticleListDTO> Articles { get; set; } = new List<ArticleListDTO>();
}
4

1 回答 1

1

问题是Repeater可能使用客户端渲染模式(这是默认模式)。当它呈现 HTML 时,它呈现如下内容:

<div data-bind="foreach: something">
    <!-- template -->
</div>

当模板被渲染时,它DataContextnull(因为模板不能包含来自项目的数据 - 它是一个模板)。

所以你在这里有两个选择:

  1. 通过添加RenderSettings.Mode="Server"Repeater.
  2. DataContext更新您的控件,使其在为空时不会调用 DataBind 。
于 2017-09-13T15:04:36.657 回答