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}}
变成
。我的问题有两个方面:

  • 怎么做?
  • 我自己需要做什么来利用这个机制(“微同步税”
Ie将
{{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]
}