通过 ngModel Binding 设置值时如何在 textarea 上触发更改事件

Posted

技术标签:

【中文标题】通过 ngModel Binding 设置值时如何在 textarea 上触发更改事件【英文标题】:How to trigger a change event on a textarea when setting the value via ngModel Binding 【发布时间】:2020-05-17 22:59:00 【问题描述】:

我在 Angular 7 项目的模板驱动形式中有一个 <textarea>。 编辑对象时,表单会预先填充当前值。我想通过修改元素样式通过[(ngModel)]="property"绑定更改内容时自动调整<textarea>的大小。

area.style.overflow = 'hidden';
area.style.height = '0';
area.style.height = area.scrollHeight + 'px';

代码通常可以工作,但我找不到合适的事件来触发它。 订阅<textarea>change 事件仅适用于键盘输入。使用(ngModelChange)="adjustTextAreaSize($event)" 具有相同的行为。

我尝试在 ngOnInit() 函数的末尾执行我的调整大小代码,但实际的 html 控件此时似乎还没有任何内容。

有没有人知道哪个事件可以在这里解决问题? 一开始似乎是一个相当容易的任务,但我已经打破了一个多小时的烦恼......不可能是一个如此困难的任务,不是吗?

【问题讨论】:

【参考方案1】:

是的,有一个非常简单的解决方案。 将您的 textarea 包裹在 form 中并尝试以下代码:-

HTML

<form #form="ngForm">
   <textarea>....</textarea>
</form>

TS

@ViewChild('form') ngForm: NgForm;
ngOnInit() 
  this.subscription = this.ngForm.form.valueChanges.subscribe(resp => 
    
      console.log(resp); // You get your event here
    
)


ngOnDestroy() 
  this.subscription.unsubscribe();

【讨论】:

通常这是有效的,但提到的&lt;textarea&gt; 已经是更大的&lt;form&gt; 的一部分,并且该事件为表单的每个控件调用一次。因此,我从@Xinan 那里选择了解决方案,但还是谢谢!【参考方案2】:

通过 ngModel Binding 设置值时触发 textarea 上的更改事件

如果这样做会导致无限触发。

如果您不想以更被动的方式监控输入模型的变化,一个更快的解决方案(但有点hacky)将简单地将您的代码包装在setTimeout 中的ngOnInit()ngAfterViewInit() 中提到它不起作用。

setTimeout(() => 
  updateSize();
);

【讨论】:

有点 hacky,是的,但是自从使用 html 和 JS 以来我已经习惯了 :) 但是因为我在 ngOnInit() 中调用了一个异步函数来启动一个 API 请求和一个不能在那里使用 await,我不得不把 setTimeout(...) 放在这个异步函数的末尾。谢谢!

以上是关于通过 ngModel Binding 设置值时如何在 textarea 上触发更改事件的主要内容,如果未能解决你的问题,请参考以下文章

如何使 Binding 尊重 DependencyProperty 值强制?

编辑值时输入失去焦点。使用 ngFor 和 ngModel。角5

如果我使用 ngModel、ngValue 以及如何在选择中添加占位符,如何设置选择的默认值

如何使用 ngModel 在 div 的 innerhtml 属性上实现 2 路数据绑定?

当被 JavaScript 更改时,Angular 无法通过 [(ngModel)] 获取输入值

在 Angular 2 中加载第一页时设置 [(ngModel)] 的值