Angular2:ngfor是如何扩展的
我知道教科书规定,Angular2:ngfor是如何扩展的,angular,angular2-template,Angular,Angular2 Template,我知道教科书规定,{{{foo.stuff}}变成…。我的问题有两个方面: 怎么做? 我自己需要做什么来利用这个机制(“微同步税” Ie将{{item.stuff}}转换为{{item.stuff}} 自从我自上而下地阅读ngFor的源代码以来,我只能假设这个黑暗的魔法就在编译器的某个地方,我在github上下翻来覆去,但我不能对它指手画脚。救命啊 *ngFor,*ngIf。。。是结构性指令 将其应用于元素或在其前面加上* 从'@angular/core'导入{指令,输入}; 从“@ang
{{{foo.stuff}}
变成…
。我的问题有两个方面:
- 怎么做?
- 我自己需要做什么来利用这个机制(“微同步税”
{{item.stuff}}
转换为{{item.stuff}}
自从我自上而下地阅读ngFor的源代码以来,我只能假设这个黑暗的魔法就在编译器的某个地方,我在github上下翻来覆去,但我不能对它指手画脚。救命啊
*ngFor
,*ngIf
。。。是结构性指令
将其应用于
元素或在其前面加上*
从'@angular/core'导入{指令,输入};
从“@angular/core”导入{TemplateRef,ViewContainerRef};
@指令({选择器:'[myuncer]'})
出口类非关税指令{
建造师(
私有templateRef:templateRef,
私有viewContainer:ViewContainerRef
) { }
@Input()设置MyInspect(条件:布尔值){
如果(!条件){
this.viewContainer.createEmbeddedView(this.templateRef);
}否则{
this.viewContainer.clear();
}
}
}
是的,所有的魔法都发生在编译器中 让我们以这个模板为例:
<div *ngFor="let foo of foobars">{{foo}}</div>
此方法返回EmbeddedTemplateAst
。这与:
<template ngFor let-foo [ngForOf]="foobars"><div>{{foo}}</div></template>
因此,您可以编写以下指令:
@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]
}
@指令({
选择器:'[dir]'
})
导出类MyDirective{
@输入()
迪尔夫:任何;
@输入()
德克:任何;
ngAfterViewInit(){
log(this.dirV,this.dirK);
}
}
@组成部分({
选择器:“我的应用程序”,
模板:`Angular 2 Systemjs start
{foo}
`,
指令:[我的指令]
})
导出类AppComponent{
foobars=[1,2,3];
arr=[3,4,5]
}
下面是相应的
*dir="let foo v foobars" => [dirV]="foobars"
另见
你可以在这里找到活生生的例子是!!!昨天我算出了传递的上下文,我在编译器中找到了模板前缀,所以我有点开始了,但你的确认让我确信。我现在明白了它是如何将
*dir=“let foo”
转换成模板dir let foo
,但它如何知道如何将foobars的转换成[ngForOf]=“foobars”
?ngFor前缀来自哪里?它如何知道哪一个变成let,哪一个以指令名称作为第二个指令的前缀?我不确定,但似乎*dir=“let-foo-of-foobars”
将是[dirOf]=”工具栏*dir=“let-foo-v-foobars”
[dirV]=”foobars“
@yurzui,还有,您是如何调试ts
文件的?我创造了一个新的世界。似乎在最新的npm版本中,他们捆绑了所有没有sourcemapsYes的东西,我知道:)我在寻求更先进的做事方式。
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;
<template ngFor let-foo [ngForOf]="foobars"><div>{{foo}}</div></template>
<div *myDirective="item">{{item.stuff}}</div>
<template myDirective let-item><div>{{item.stuff}}</div></template>
<div *myDirective="let item">{{item.stuff}}</div>
@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
}
}
<div *myDirective="item">{{item.stuff}}</div>
||
\/
<div template="myDirective:item">{{item.stuff}}</div>
||
\/
<template [myDirective]="item">
<div>{{item.stuff}}</div>
</template>
*dir="let foo v foobars" => [dirV]="foobars"
@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]
}