手动触发输入更改事件

时间:2020-10-05 15:26:19

标签: angular typescript angular-directive

我正在尝试制作一个自定义计数器输入组件,并且正在努力使输入值由自定义增量/减量按钮控制。

这就是我要做的:

CounterInputComponent

我想使用内容投影并将输入公开,以便像在常规数字输入中那样在表单中使用它并添加属性。因此,对输入执行指令似乎是一种方法:

<my-counter-input>
  <input [(ngModel)]="count" myInputRef />
</my-counter-input>

该组件本身将具有两个按钮和一个ng-content插槽:

<button (click)="decrement()">-</button>
<ng-content select="input"></ng-content>
<button (click)="increment()">+</button>

到目前为止,一切似乎都还不错。现在,我可以使用@ContentChild装饰器与指令进行交互。

@Component({
  selector: 'my-counter-input',
  templateUrl: './counter-input.component.html',
  styleUrls: ['./counter-input.component.scss'],
})
export class CounterInputComponent {
  @ContentChild(InputRefDirective)
  public input: InputRefDirective;

  constructor() {}

  public increment() {
    this.input.increment();
  }
  public decrement() {
    this.input.decrement();
  }
}

我想这就是问题所在。我将输入元素的值绑定到指令,但是增量/减量方法都不会对本机输入值产生任何影响。我想对本机输入值进行双向绑定,但事实并非如此。

@Directive({
  selector: 'input [myInputRef]',
})
export class InputRefDirective {
  @HostBinding('type') readonly type = 'number';

  @HostBinding('value') value = 5;

  public increment() {
    this.value++;
  }
  public decrement() {
    this.value--;
  }
}

我不确定该怎么做。如何更新本机输入的值并触发本机更改事件?

3 个答案:

答案 0 :(得分:1)

使用NgControl

所有基于FormControl的指令都扩展的基类。它绑定一个 DOM元素的FormControl对象。

我们可以在指令中注入NgControl,Angular DI框架将为我们提供最接近的表单控制指令。然后,我们可以将值动态设置为formControl。

#Input data:
structure(list(Gene = c("BRCA2", "SLC25A20", "GLS", "IKZF4", 
"NRIP3", "SENP1", "SLC27A6", "SRFBP1", "OBFC1", "STEAP2"), Score1 = c(0.7, 
0.2644568, 0.4560175, 0.7468294, 0.844639, 0.5372014, 0.6321821, 
0.2293986, 0.2279012, 0.2239941), Score2 = c(0.7, 0.486816, 0.663101, 
0.2189585, 0.4570968, 0.1724868, 0.1218227, 0.2688244, 0.2187441, 
0.2001475)), row.names = c(NA, -10L), class = c("data.table", 
"data.frame"))

Forked Working Example

答案 1 :(得分:1)

您可以告诉ngModel在初始化和每次更改时进行更新

public increment() {
  this.value++;
  this.updateNgModel(this.value);
}

public decrement() {
  this.value--;
  this.updateNgModel(this.value);
}

private updateNgModel(value: number) {
  this.ngModel.update.emit(value);
}

https://stackblitz.com/edit/angular-ivy-mw2ltg?file=src/app/input-ref.directive.ts

答案 2 :(得分:0)

除非必须使用内容投影并让父级提供输入控件/模板,否则您只需将可重用组件创建为处理所有内容的独立组件即可。这样比较简单。 Here is a forked example

但是已经给出的其他两个示例确实解决了您面临的更新问题。