Ja, alle Magie im Compiler passiert.
Lassen Sie uns diese Vorlage nehmen:
<div *ngFor="let foo of foobars">{{foo}}</div>
Zuerst wird auf die folgende umgewandelt werden:
<div template="ngFor let foo of foobars>{{foo}}</div>
Und dann:
<template ngFor let-foo [ngForOf]="foobars"><div>{{foo}}</div></template>
In Angular2 rc.4 es sieht aus wie dies
Zuerst wird ast Baumknoten (Abstract Syntax-Baum-Knoten) erzeugt und dann alles geht wie in den TemplateParseVisitor.visitElement
(https://github.com/angular/angular/blob/2.0.0-rc.4/modules/%40angular/compiler/src/template_parser.ts#L284) speziell am Boden (https://github.com/angular/angular/blob/2.0.0-rc.4/modules/%40angular/compiler/src/template_parser.ts#L394)
if (hasInlineTemplates) {
var templateCssSelector = createElementCssSelector(TEMPLATE_ELEMENT, templateMatchableAttrs);
var templateDirectiveMetas = this._parseDirectives(this.selectorMatcher, templateCssSelector);
var templateDirectiveAsts = this._createDirectiveAsts(
true, element.name, templateDirectiveMetas, templateElementOrDirectiveProps, [],
element.sourceSpan, []);
var templateElementProps: BoundElementPropertyAst[] = this._createElementPropertyAsts(
element.name, templateElementOrDirectiveProps, templateDirectiveAsts);
this._assertNoComponentsNorElementBindingsOnTemplate(
templateDirectiveAsts, templateElementProps, element.sourceSpan);
var templateProviderContext = new ProviderElementContext(
this.providerViewContext, parent.providerContext, parent.isTemplateElement,
templateDirectiveAsts, [], [], element.sourceSpan);
templateProviderContext.afterElement();
parsedElement = new EmbeddedTemplateAst(
[], [], [], templateElementVars, templateProviderContext.transformedDirectiveAsts,
templateProviderContext.transformProviders,
templateProviderContext.transformedHasViewContainer, [parsedElement], ngContentIndex,
element.sourceSpan);
}
return parsedElement;
Diese Methode gibt EmbeddedTemplateAst
. Es ist das gleiche wie:
<template ngFor let-foo [ngForOf]="foobars"><div>{{foo}}</div></template>
Wenn Sie aktivieren möchten:
<div *myDirective="item">{{item.stuff}}</div>
in
<template myDirective let-item><div>{{item.stuff}}</div></template>
dann müssen Sie die folgende Syntax verwenden:
<div *myDirective="let item">{{item.stuff}}</div>
Aber In diesem Fall werden Sie den Kontext nicht weitergeben. Ihre benutzerdefinierte Struktur Richtlinie könnte wie folgt aussehen:
@Directive({
selector: '[myDirective]'
})
export class MyDirective {
constructor(
private _viewContainer: ViewContainerRef,
private _templateRef: TemplateRef<any>) {}
@Input() set myDirective(prop: Object) {
this._viewContainer.clear();
this._viewContainer.createEmbeddedView(this._templateRef, prop); <== pass context
}
}
Und Sie können es gerne verwenden:
<div *myDirective="item">{{item.stuff}}</div>
||
\/
<div template="myDirective:item">{{item.stuff}}</div>
||
\/
<template [myDirective]="item">
<div>{{item.stuff}}</div>
</template>
Ich hoffe, dies wird Ihnen helfen zu verstehen, wie strukturelle Richtlinien arbeiten.
Update:
Mal sehen, wie es funktioniert (plunker)
*dir="let foo v foobars" => [dirV]="foobars"
So können Sie die folgende Anweisung schreiben:
@Directive({
selector: '[dir]'
})
export class MyDirective {
@Input()
dirV: any;
@Input()
dirK: any;
ngAfterViewInit() {
console.log(this.dirV, this.dirK);
}
}
@Component({
selector: 'my-app',
template: `<h1>Angular 2 Systemjs start</h1>
<div *dir="let foo v foobars k arr">{ foo }</div>
`,
directives: [MyDirective]
})
export class AppComponent {
foobars = [1, 2, 3];
arr = [3,4,5]
}
Hier ist die entsprechende Plunker
Siehe auch
Live-Beispiel finden Sie hier https://alexzuza.github.io/enjoy-ng-parser/
Ja !!! Ich habe gestern den passierenden Kontext herausgefunden, und ich fand die TEMPLATE_PREFIX-Sache im Compiler, also kam ich irgendwie dazu, aber Ihre Bestätigung bestätigt mir. – TDaver
Ich verstehe jetzt, wie es '* dir =" let foo "' in 'template dir let-foo' verwandelt, aber woher weiß es,'ofobars' in' [ngForOf] = "foobars" '' zu verwandeln? Woher kommt das ngFor-Präfix? Woher weiß es, welches in ein Let zu verwandeln ist und welches mit dem Namen der Direktive für eine zweite Direktive vorangestellt wird? – TDaver
Ich bin mir nicht sicher, aber scheint '* dir =" let foo von foobars "' wird sein '[dirOf] =" toolbars " – yurzui