javascript - #selector fungerar endast för rootelementet, inte för barn i Angular


Jag är förvirrad över selektorn när jag definierar en selektor för rootelementet (App-komponent) med hjälp av id som nedan. Jag kan rendera komponenten.

index.html

<body>

  <div id="root"></div>

</body>

app.component.ts

import { Component } from '@angular/core';

  @Component({
     selector: '#root',
     templateUrl: './app.component.html',
     styleUrls: ['./app.component.scss']
  })
  export class AppComponent {
    title = 'helloworld';

}

app.component.html

div class='my-text' >My Root Component</div>


<div id='child'></div>

Jag kan rendera föräldrakomponenten, men jag kan inte rendera barnkomponenten om jag följer samma regel när jag definierar i barnväljaren

@Component({
    selector: '#child',
    templateUrl: './child1.component.html',
    styleUrls: ['./child1.component.scss']
})

Men jag kan rendera barnkomponenten om jag ändrar selektorn till selector=[id=child]

Varför fungerar selektordefinitionen för förälder men misslyckas för barnet?

Angular version 8

Svar #1

Angular-kompilatorn använder följande regexp för att parsa selektor:

const _SELECTOR_REGEXP = new RegExp(
    '(\\:not\\()|' +           //":not("
        '([-\\w]+)|' +         // "tag"
        '(?:\\.([-\\w]+))|' +  // ".class"
        // "-" should appear first in the regexp below as FF31 parses "[.-\w]" as a range
        '(?:\\[([-.\\w*]+)(?:=([\"\']?)([^\\]\"\']*)\\5)?\\])|' +  // "[name]", "[name=value]",
                                                                   // "[name="value"]",
                                                                   // "[name='value']"
        '(\\))|' +                                                 // ")"
        '(\\s*,\\s*)',                                             // ","
'g');

Som du kan se finns det ingen selektor med id.

Dessutom kommer dina selektorer #root och #child att matchas med root och child-element. Så, om du ersätter <div id='child'></div> med <child></child> kommer barnkomponenten att renderas.

Varför fungerar root-väljaren?

Det beror på att rotkomponenten behandlas speciellt och startas som en dynamisk komponent genom att använda följande kod:

componentFactory.create(Injector.NULL, [], selectorOrNode, ngModule);
                                           ^^^^^^^^^^^^^^
                                             #root

Där under huven använder Angular document.querySelector(selectorOrNode) för att hitta ett dedikerat element om vi tillhandahöll en sträng.

Å andra sidan renderas alla inbäddade komponenter bara om deras selektorer matchar mot element i mallen.