Понимание внутреннего устройства QuickGrid: «Отложить взлом»
Я изучаю исходный код QuickGrid от Blazor (ASP.NET Core 8) .Реализация использует некоторые внутренние знания о том, как Blazor обрабатывает фактическую отрисовку, чтобы собрать все дочерние компоненты ColumnBase. Это делается путем запуска и завершения «сеанса сбора», и во время этого сеанса все дочерние компоненты ColumnBase присоединяются к контексту каскадной сетки.
<CascadingValue TValue="InternalGridContext<TGridItem>" IsFixed="true" Value="@_internalGridContext">
@{ StartCollectingColumns(); }
@ChildContent
<Defer>
@{ FinishCollectingColumns(); }
<ColumnsCollectedNotifier TGridItem="TGridItem" />
@* HTML table... *@
</Defer>
</CascadingValue>
Компоненты ColumnBase внутри ChildContent выполняют следующий код в своем методе BuildRenderTree:
InternalGridContext.Grid.AddColumn(this, InitialSortDirection, IsDefaultSortColumn);
Компонент Defer построен следующим образом:
// This is used by QuickGrid to move its body rendering to the end of the render queue so we can collect
// the list of child columns first. It has to be public only because it's used from .razor logic.
public sealed class Defer : ComponentBase
{
[Parameter] public RenderFragment? ChildContent { get; set; }
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.AddContent(0, ChildContent);
}
}
В компоненте Defer также есть комментарий, объясняющий, что он делает, и я это понимаю. Однако я не совсем понимаю, как и почему это работает. Может ли кто-нибудь объяснить мне подробности о том, как и почему это работает?
Это каким-то образом говорит о том, что RenderFragments задерживаются при рендеринге. Но для меня это не совсем интуитивно понятно. Я думаю о рендеринге как о своего рода обходе дерева левого порядка узлов, включая RenderFragments. Но похоже, что RenderFragments изначально не просматриваются.
2 ответа
Я думаю о рендеринге как о своего рода обходе дерева левого порядка узлов, включая RenderFragments.
На самом деле обход осуществляется не в глубину, а скорее в ширину. Дочерние компоненты создаются при рендеринге родительского компонента, и все они визуализируются после родительского компонента.
Но похоже, что RenderFragments изначально не просматриваются.
Речь идет не о RenderFragments, а о дочерних компонентах. Насколько я могу судить, истинная цель@{ FinishCollectingColumns(); }
линия.
Без<Defer>
на тот момент столбцы еще не были зарегистрированы. Поскольку столбцы были бы созданы, но ни один из них не был бы отображен и, следовательно, не было бы возможности вызватьAddColumn(this,)
.
Я предполагаю, что вы понимаете:
- Что такое на самом деле - делегат.
- Файлы Razor компилируются в классы C#.
- Эта разметка Razor компилируется в набор инструкций.
Когда рендерер проходит через сгенерированный
Таким образом, каждый компонент
Вы можете увидеть это, поместив фрагмент рендеринга, который фактически строит сетку, внутри подчиненного компонента —
Вы можете использовать аналогичный процесс для других типов составных элементов управления.