如何在结构指令中将函数传递给createEmbeddedView?

时间:2019-10-30 16:49:05

标签: angular angular7 angular8

使用指令的模板:

<select>
  <ng-container *range="[1998, 2016]; let num; let fn = fn">
    <option (click)="fn()" [ngValue]="num">{{ num }} {{ fn | json }}</option>
  </ng-container>
</select>

指令为:

@Directive({
  selector: "[range]"
})
export class RangeDirective {
  _range: number[];

  constructor(private vcr: ViewContainerRef, private tpl: TemplateRef<any>) {}

  @Input()
  set range(value) {
    this.vcr.clear();
    this._range = this.generateRange(value[0], value[1]);
    this._range.forEach(num => {
      this.vcr.createEmbeddedView(this.tpl, {
        $implicit: num,
        fn: submit
      });
    });
  }

  private generateRange(from, to) {
    let arr = [];
    for (let i = from; i <= to; i++) {
      arr.push(i);
    }

    return arr;
  }
}

功能是:

let submit = () => {
  alert("Submit event");
};

我的想法是动态更改处理程序的点击次数

1 个答案:

答案 0 :(得分:3)

您的问题在这里:

(click)="fn"

应该是

(click)="fn()"

StackBlitz Example

编辑

您遇到的另一个问题是浏览器不会从click元素发出<option>事件。我可以想到两种选择:

选项1-<select> change事件:

<select #select (change)="onChange(select.value)">
  ...
  <option value="a">A</option>
  ...
</select>

不幸的是,无法将对象分配给<option>元素,因此该方法无济于事,因为无法将函数传递给每个选项唯一的change事件处理程序

选项2-ngModelChange

这种方法应该可以完成您想做的事情:

<select ngModel (ngModelChange)="$event.fn(); onChange($event.value)">
  <option *range="[1998, 2016]; let num; let fn = fn" [ngValue]e="{ fn: fn, value: num }">{{ num }}</option>
</select>

StackBlitz Example