Javascript 角度:如何将索引变量从自定义指令共享到另一个指令?

Javascript 角度:如何将索引变量从自定义指令共享到另一个指令?,javascript,angular,typescript,angular2-directives,Javascript,Angular,Typescript,Angular2 Directives,我正在尝试在两个自定义指令之间共享一个索引变量:ngLoop和ngDN 这是ngLoop的代码: import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core'; @Directive({ selector: '[ngLoop]' }) export class NgLoopDirective { @Input() set ngLoop(iter_count: number) {

我正在尝试在两个自定义指令之间共享一个索引变量:
ngLoop
ngDN

这是ngLoop的代码:

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[ngLoop]'
})
export class NgLoopDirective {

  @Input() set ngLoop(iter_count: number) {
    this.container.clear();
    for (let i=0; i<iter_count; i++) {
      this.container.createEmbeddedView(this.template);
    }
  }

  constructor(private template: TemplateRef<any>,
              private container: ViewContainerRef) {}

}
import { Directive, Input, ElementRef, Renderer2 } from '@angular/core';

@Directive({
  selector: '[ngDN]'
})
export class NgDNDirective {

  @Input() set ngDN(dn: number) {
    this.renderer.setAttribute(this.elRef, 'data-num', dn.toString());
  }

  constructor(private elRef: ElementRef, private renderer: Renderer2) {}

}
问题:

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[ngLoop]'
})
export class NgLoopDirective {

  @Input() set ngLoop(iter_count: number) {
    this.container.clear();
    for (let i=0; i<iter_count; i++) {
      this.container.createEmbeddedView(this.template);
    }
  }

  constructor(private template: TemplateRef<any>,
              private container: ViewContainerRef) {}

}
import { Directive, Input, ElementRef, Renderer2 } from '@angular/core';

@Directive({
  selector: '[ngDN]'
})
export class NgDNDirective {

  @Input() set ngDN(dn: number) {
    this.renderer.setAttribute(this.elRef, 'data-num', dn.toString());
  }

  constructor(private elRef: ElementRef, private renderer: Renderer2) {}

}
现在,每当我尝试如何成功地从下面的html代码工作

<div *ngLoop="products.categories.length; let i = index">
                <a href="#"
                   [ngDN]="i"></a>
            </div>

我得到一个错误,说:

错误类型错误:无法读取未定义的属性“toString” at NgDNDirective.set[作为ngDN](ng dn.directive.ts:9) 在updateProp(core.es5.js:11102) 在checkAndUpdateDirectiveInline(core.es5.js:10794) 在checkAndUpdateNodeLine(core.es5.js:12332) 在checkAndUpdateNode(core.es5.js:12271) 在debugCheckAndUpdateNode(core.es5.js:13132) 在debugCheckDirectivesFn(core.es5.js:13073) 在Object.eval[作为updateDirectives](HomeComponent.html:38) 在Object.debugUpdateDirectives[作为updateDirectives](core.es5.js:13058) 在checkAndUpdateView(core.es5.js:12238)

从中我了解到索引变量
I
没有正确共享


共享索引变量的正确方法是什么?

要实现的语法的简化形式如下所示

<!-- sugared -->
<div *ngLoop="10; let i = index">
  <a href="#" [ngDN]="i"></a>
</div>

<!-- desugared -->
<ng-template [ngLoop]="10" let-i="index">
  <div>
    <a href="#" [ngDN]="i"></a>
  </div>
</ng-template>
for (let i = 0; i < iter_count; i++) {
  this.container.createEmbeddedView(this.template, {
    index: i,
  });
}
这意味着变量
索引
将在
ng模板
中可用。通过说
let-i=“index”
,您可以将该模板的
索引值分配给局部变量
i
,该变量仅在模板中的
ng模板内可用

A。打开控制台,你会看到数字



不过,渲染器会有问题,因为在调用输入的setter时,元素还不能用于样式设置。您需要将其延迟到视图初始化后的
。但是您现在可以
console.log
并注释出渲染器方法,以查看上述方法是否确实有效。

您的ngLoop指令需要导出索引值。默认情况下,你没有类似的东西。这存在于默认的NgForOf指令中,因为它是在指令实现中导出的。@AdrianFaciu OK。但是,我怎样才能导出它呢?看看这是一个好的开始。@AdrianFaciu我不想做某种c/p,而是想学习如何做。谢谢你的解释。我明白了,我尽力让它工作,但没有成功——我也犯了同样的错误。这是关于代码更新的:。我不确定如何在Codepen中运行Angular。试试闪电战。好的,我通过使用
ng template
let-I=index
修复了错误。但现在我面临另一个错误,即“error-TypeError:el.setAttribute不是函数”-这是因为我没有将setter方法推迟到
AfterViewInit
event:我是否使用了EventEmitter,为了实现这一点,我认为最简单的方法是将渲染器调用封装在
setTimeout
中。我不确定您希望在这里使用EventEmitter实现什么。我建议打开一个新问题,因为我认为上面的答案正确地回答了“为什么不设置索引”。到处使用
setTimeout
不是一个好地方。在做一些高级事情时,在这里和那里使用它,并正确地封装这些调用——这没什么不好的。