1

I have this structural directive:

@Directive({
  // tslint:disable-next-line:directive-selector
  selector: '[cycle]'
})
export class CycleDirective {
  private cycle$: any;

  constructor(
    private tRef: TemplateRef<any>,
    private vcRef: ViewContainerRef) { }

  @Input() cycleInterval: number | Observable<any> = 1000;
  @Input() set cycle(source: Array<any[]>) {
    const interval$ = ofType(Number, this.cycleInterval) ?
      Observable.timer(0, this.cycleInterval as number) : this.cycleInterval;

    if (!hasProperty(interval$, 'subscribe')) {
      throw new Error('Input interval must be Number or Observable');
    }

    this.cycle$ = Observable.of(source)
      .combineLatest(interval$ as Observable<any>)
      .map(([items, index]) => items[cycle(index - 1, items.length)])
      .forEach(item => {
        this.vcRef.clear();
        this.vcRef.createEmbeddedView(this.tRef);
      });
  }

}

How do I export current item, index (or anything) to be able to use it in templates?

<div *cycle="['a', 'b', 'c']; interval: 2000">
  testing: <!-- current item -->
</div>

Ideally it should be used like ngFor:

<div *cycle="let item of ['a', 'b', 'c']; interval: 2000">{{ item }}</div>
Sasxa
  • 40,334
  • 16
  • 88
  • 102

1 Answers1

2

You can try:

this.vcRef.createEmbeddedView(this.tRef, { $implicit: item, index: index });

And in template:

*cycle="['a', 'b', 'c']; interval: 2000; let item; let i = index"

For your requirement:

directive.ts

@Directive({
  // tslint:disable-next-line:directive-selector
  selector: '[cycle][cycleOf]'
                     ^^^^^^ but we can omit this
})
export class CycleDirective {
  private cycle$: any;

  constructor(
    private tRef: TemplateRef<any>,
    private vcRef: ViewContainerRef) { }

  @Input() cycleInterval: number | Observable<any> = 1000;
  @Input() set cycleOf(source: Array<any[]>) {
                   ^^^ required
    ...
        this.vcRef.createEmbeddedView(this.tRef, { $implicit: item, index: index });
    ...
  }

}

parent-template.html:

<div *cycle="let item of ['a', 'b', 'c']; interval: 2000; let i = index">
  {{ item }} {{ i }}
</div>

See also

yurzui
  • 205,937
  • 32
  • 433
  • 399