Angular 手动触发输入更改事件

Angular 手动触发输入更改事件,angular,typescript,angular-directive,Angular,Typescript,Angular Directive,我正在尝试制作一个自定义计数器输入组件,我正在努力让输入值由自定义递增/递减按钮控制 这就是我想做的: 我想使用内容投影并公开输入,以便在表单中使用它,并像在常规数字输入中一样添加属性。因此,输入指令似乎是一种方法: 组件本身将有两个按钮和一个ng content-插槽: - + 到目前为止,一切似乎都很好。现在我可以使用@ContentChild装饰器与该指令交互 @组件({ 选择器:“我的计数器输入”, templateUrl:'./counter input.component.h

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

这就是我想做的:

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


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

-
+
到目前为止,一切似乎都很好。现在我可以使用
@ContentChild
装饰器与该指令交互

@组件({
选择器:“我的计数器输入”,
templateUrl:'./counter input.component.html',
styleUrls:['./计数器输入.component.scss'],
})
导出类计数器输入组件{
@ContentChild(InputRefDirective)
公共输入:inputreffdirective;
构造函数(){}
公共增量(){
this.input.increment();
}
公共减量{
this.input.decrement();
}
}
我想这就是问题所在。我将输入元素的值绑定到指令,但增量/减量方法对本机输入值都没有任何影响。我希望对本机输入值进行双向绑定,但情况似乎并非如此

@指令({
选择器:“输入[myInputRef]”,
})
导出类inputref指令{
@HostBinding('type')只读类型='number';
@主机绑定(“值”)值=5;
公共增量(){
这个.value++;
}
公共减量{
这是价值观;
}
}
我不知道该怎么办。如何更新本机输入的值并触发本机更改事件?

使用

所有基于FormControl的指令扩展的基类。它绑定了一个 将FormControl对象转换为DOM元素

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

import { Directive, HostBinding, AfterViewInit } from "@angular/core";
import { NgControl } from "@angular/forms";

@Directive({
  selector: "[appInput]"
})
export class InputDirective implements AfterViewInit {
  @HostBinding("type") readonly type = "number";

   value = 5;
 

  ngAfterViewInit(){
     setTimeout(()=>{this.control.control.setValue(this.value)})
  }

  constructor(private control: NgControl) {
    
  }

  public increment() {
    this.control.control.setValue(this.value++);
  }
  public decrement() {
    this.control.control.setValue(this.value--);
  }
}
使用

所有基于FormControl的指令扩展的基类。它绑定了一个 将FormControl对象转换为DOM元素

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

import { Directive, HostBinding, AfterViewInit } from "@angular/core";
import { NgControl } from "@angular/forms";

@Directive({
  selector: "[appInput]"
})
export class InputDirective implements AfterViewInit {
  @HostBinding("type") readonly type = "number";

   value = 5;
 

  ngAfterViewInit(){
     setTimeout(()=>{this.control.control.setValue(this.value)})
  }

  constructor(private control: NgControl) {
    
  }

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

您可以告诉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);
}

您可以告诉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);
}

除非您必须使用内容投影并让父级提供输入控件/模板,否则您只需将可重用组件创建为一个独立的组件来处理一切。那样比较简单


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

除非您必须使用内容投影并让父级提供输入控件/模板,否则您可以将可重用组件创建为一个独立的组件来处理所有事情。那样比较简单


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

谢谢!我正在考虑这一点,但我发现在组件中隐藏输入存在一些问题。我想了解更多关于这些问题的信息。对于可共享组件,我们已经很好地使用了这种模式。您还可以使用ControlValueAccessor模式使输入能够很好地处理反应式表单(而不是执行如图所示的输出事件)。该策略可能会有所帮助?这里是另一个分叉版本,为简单起见,它接受FormControl作为输入(而不是controlValueAccessor),并且易于在表单中重用。通过这种方式,您可以使用反应式表单并将控制行为封装在可重用组件中。也许这是有帮助的:)我主要是指在感谢中提出的问题!我正在考虑这一点,但我发现在组件中隐藏输入存在一些问题。我想了解更多关于这些问题的信息。对于可共享组件,我们已经很好地使用了这种模式。您还可以使用ControlValueAccessor模式使输入能够很好地处理反应式表单(而不是执行如图所示的输出事件)。该策略可能会有所帮助?这里是另一个分叉版本,为简单起见,它接受FormControl作为输入(而不是controlValueAccessor),并且易于在表单中重用。通过这种方式,您可以使用反应式表单并将控制行为封装在可重用组件中。也许这是有帮助的:)我主要是指在感谢中提出的问题!最后,我将这个问题与另一个答案结合起来,并拥有可选的NgControl和可选的NgModel依赖项。谢谢!最后,我将这个问题与另一个答案结合起来,并拥有可选的NgControl和可选的NgModel依赖项。谢谢!最后,我将这个问题与另一个答案结合起来,并拥有可选的NgControl和可选的NgModel依赖项。谢谢!最后,我将这一点与另一个答案结合起来,并具有可选的NgControl和可选的NgModel依赖项。