feat(ivy): add support for the ngProjectAs attribute (#22498)
PR Close #22498
This commit is contained in:

committed by
Alex Eagle

parent
f86d8ae0fd
commit
2c75acc5b3
@ -11,7 +11,7 @@ import './ng_dev_mode';
|
||||
import {assertEqual, assertLessThan, assertNotEqual, assertNotNull, assertNull, assertSame} from './assert';
|
||||
import {LContainer, TContainer} from './interfaces/container';
|
||||
import {LInjector} from './interfaces/injector';
|
||||
import {CssSelector, LProjection} from './interfaces/projection';
|
||||
import {CssSelector, LProjection, NG_PROJECT_AS_ATTR_NAME} from './interfaces/projection';
|
||||
import {LQueries} from './interfaces/query';
|
||||
import {LView, LViewFlags, LifecycleStage, RootContext, TData, TView} from './interfaces/view';
|
||||
|
||||
@ -560,8 +560,12 @@ function setUpAttributes(native: RElement, attrs: string[]): void {
|
||||
|
||||
const isProc = isProceduralRenderer(renderer);
|
||||
for (let i = 0; i < attrs.length; i += 2) {
|
||||
isProc ? (renderer as ProceduralRenderer3).setAttribute(native, attrs[i], attrs[i | 1]) :
|
||||
native.setAttribute(attrs[i], attrs[i | 1]);
|
||||
const attrName = attrs[i];
|
||||
if (attrName !== NG_PROJECT_AS_ATTR_NAME) {
|
||||
const attrVal = attrs[i + 1];
|
||||
isProc ? (renderer as ProceduralRenderer3).setAttribute(native, attrName, attrVal) :
|
||||
native.setAttribute(attrName, attrVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1279,9 +1283,23 @@ export function directiveRefresh<T>(directiveIndex: number, elementIndex: number
|
||||
* each projected node belongs (it re-distributes nodes among "buckets" where each "bucket" is
|
||||
* backed by a selector).
|
||||
*
|
||||
* @param selectors
|
||||
* This function requires CSS selectors to be provided in 2 forms: parsed (by a compiler) and text,
|
||||
* un-parsed form.
|
||||
*
|
||||
* The parsed form is needed for efficient matching of a node against a given CSS selector.
|
||||
* The un-parsed, textual form is needed for support of the ngProjectAs attribute.
|
||||
*
|
||||
* Having a CSS selector in 2 different formats is not ideal, but alternatives have even more
|
||||
* drawbacks:
|
||||
* - having only a textual form would require runtime parsing of CSS selectors;
|
||||
* - we can't have only a parsed as we can't re-construct textual form from it (as entered by a
|
||||
* template author).
|
||||
*
|
||||
* @param selectors A collection of parsed CSS selectors
|
||||
* @param rawSelectors A collection of CSS selectors in the raw, un-parsed form
|
||||
*/
|
||||
export function projectionDef(index: number, selectors?: CssSelector[]): void {
|
||||
export function projectionDef(
|
||||
index: number, selectors?: CssSelector[], textSelectors?: string[]): void {
|
||||
const noOfNodeBuckets = selectors ? selectors.length + 1 : 1;
|
||||
const distributedNodes = new Array<LNode[]>(noOfNodeBuckets);
|
||||
for (let i = 0; i < noOfNodeBuckets; i++) {
|
||||
@ -1296,7 +1314,7 @@ export function projectionDef(index: number, selectors?: CssSelector[]): void {
|
||||
// - there are selectors defined
|
||||
// - a node has a tag name / attributes that can be matched
|
||||
if (selectors && componentChild.tNode) {
|
||||
const matchedIdx = matchingSelectorIndex(componentChild.tNode, selectors !);
|
||||
const matchedIdx = matchingSelectorIndex(componentChild.tNode, selectors, textSelectors !);
|
||||
distributedNodes[matchedIdx].push(componentChild);
|
||||
} else {
|
||||
distributedNodes[0].push(componentChild);
|
||||
|
Reference in New Issue
Block a user