(tView: TView, lView: LView<T>, context: T)
| 91 | * - creating child components defined in a given view. |
| 92 | */ |
| 93 | export function renderView<T>(tView: TView, lView: LView<T>, context: T): void { |
| 94 | ngDevMode && assertEqual(isCreationMode(lView), true, 'Should be run in creation mode'); |
| 95 | ngDevMode && assertNotReactive(renderView.name); |
| 96 | enterView(lView); |
| 97 | try { |
| 98 | const viewQuery = tView.viewQuery; |
| 99 | if (viewQuery !== null) { |
| 100 | executeViewQueryFn<T>(RenderFlags.Create, viewQuery, context); |
| 101 | } |
| 102 | |
| 103 | // Execute a template associated with this view, if it exists. A template function might not be |
| 104 | // defined for the root component views. |
| 105 | const templateFn = tView.template; |
| 106 | if (templateFn !== null) { |
| 107 | executeTemplate<T>(tView, lView, templateFn, RenderFlags.Create, context); |
| 108 | } |
| 109 | |
| 110 | // This needs to be set before children are processed to support recursive components. |
| 111 | // This must be set to false immediately after the first creation run because in an |
| 112 | // ngFor loop, all the views will be created together before update mode runs and turns |
| 113 | // off firstCreatePass. If we don't set it here, instances will perform directive |
| 114 | // matching, etc again and again. |
| 115 | if (tView.firstCreatePass) { |
| 116 | tView.firstCreatePass = false; |
| 117 | } |
| 118 | |
| 119 | // Mark all queries active in this view as dirty. This is necessary for signal-based queries to |
| 120 | // have a clear marking point where we can read query results atomically (for a given view). |
| 121 | lView[QUERIES]?.finishViewCreation(tView); |
| 122 | |
| 123 | // We resolve content queries specifically marked as `static` in creation mode. Dynamic |
| 124 | // content queries are resolved during change detection (i.e. update mode), after embedded |
| 125 | // views are refreshed (see block above). |
| 126 | if (tView.staticContentQueries) { |
| 127 | refreshContentQueries(tView, lView); |
| 128 | } |
| 129 | |
| 130 | // We must materialize query results before child components are processed |
| 131 | // in case a child component has projected a container. The LContainer needs |
| 132 | // to exist so the embedded views are properly attached by the container. |
| 133 | if (tView.staticViewQueries) { |
| 134 | executeViewQueryFn<T>(RenderFlags.Update, tView.viewQuery!, context); |
| 135 | } |
| 136 | |
| 137 | // Render child component views. |
| 138 | const components = tView.components; |
| 139 | if (components !== null) { |
| 140 | renderChildComponents(lView, components); |
| 141 | } |
| 142 | } catch (error) { |
| 143 | // If we didn't manage to get past the first template pass due to |
| 144 | // an error, mark the view as corrupted so we can try to recover. |
| 145 | if (tView.firstCreatePass) { |
| 146 | tView.incompleteFirstPass = true; |
| 147 | tView.firstCreatePass = false; |
| 148 | } |
| 149 | |
| 150 | throw error; |
no test coverage detected
searching dependent graphs…