如何使用模型驱动/反应形式修改指令中的输入值

Posted

技术标签:

【中文标题】如何使用模型驱动/反应形式修改指令中的输入值【英文标题】:How to modify input values in directives with model driven / reactive forms 【发布时间】:2016-12-30 10:42:02 【问题描述】:

我想实现一个“TrimDirective”,它使用 Angular 2 RC 5 和模型驱动/反应形式从输入字段中删除前导和尾随空格。

我设法更改了输入字段的值,但是在myForm.valueChanges() 的组件中没有得到新值。

查看此插件:http://plnkr.co/edit/ruzqCh?p=preview

指令改变值时如何触发formGroup的更新?

模板

<form [formGroup]="myForm">
  <input formControlName="name" trim>
</form>
latest value: - latestValue -

组件

@Component(
  selector: 'my-app',
  templateUrl: 'app/app.html'
)
export class AppComponent implements OnInit 

  private myForm: FormGroup;
  private latestValue: string;

  ngOnInit() 
    this.myForm = new FormGroup(
      name: new FormControl(),
    );
    this.myForm.valueChanges.subscribe(v => this.latestValue = v.name)
  

指令

@Directive(
    selector: '[trim]'
)

export class TrimDirective 

    private el: any;

    constructor(
        el: ElementRef
    )
        this.el = el.nativeElement;
    

    @HostListener('keypress')
    onEvent() 
        setTimeout(() =>  // get new input value in next event loop!
            let value: string = this.el.value;
            if(value && (value.startsWith(' ') || value.endsWith(' '))) 
                console.log('trim!');
                this.el.value = value.trim();
            
        ,0);
    

【问题讨论】:

尝试将onEvent更改为onKeyDown @viku 这不是问题。问题是this.el.value = value.trim(); 更新了输入的值和 DOM,但 Angular 的“模型”没有改变。指令如何强制detectChanges() 或发出事件或某事/任何事(访问组件/FormGroup/FormControl?) 【参考方案1】:

您可以在元素上创建并触发更改事件,以告诉 Angular 更新模型值。

let event: Event = document.createEvent("Event");
event.initEvent('input', true, true);
Object.defineProperty(event, 'target', value: this.elementRef.nativeElement, enumerable: true);
this.renderer.invokeElementMethod(this.elementRef.nativeElement, 'dispatchEvent', [event]);

【讨论】:

与此同时,我转向了模板驱动模型,但是,是的,谢谢,那行得通! plnkr.co/edit/CLrA3b5v1V8LgszC3Vqi?p=preview 请注意:将private renderer: Renderer 添加到指令的构造函数参数中,并将import Renderer from '@angular/core'; 添加到文件中。最后,无关:确保您使用的是正确的this 我很尴尬地说,我可能一直在尝试在上下文发生变化的事件侦听器回调中解决此问题的各种解决方案。哦 渲染器在 angular 的最后一个版本中已被弃用,而在 render2 中它没有任何 invokeElementMethod

以上是关于如何使用模型驱动/反应形式修改指令中的输入值的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2 输入指令修改表单控件值

如何在angular4中为来自ts的反应形式应用自定义指令?

如何在反应形式中采用默认值

如何在Angular2中使禁用的反应形式可编辑

如何在 Angular 中将此模板驱动的表单更改为反应式表单?

Angular 2中的模板驱动形式和反应形式有啥区别