微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

javascript – 以编程方式更新Angular 2字段

我有以下表单字段,工作正常.通过这种方式,我的意思是当我在字段中键入,粘贴等时,fooObj.expDate实时更新得很好并且验证发生.我有标签,这对我自己来说很明显.
<pre>{{fooObj.someDate | json}}</pre>

  <div class="form-group inline-form__input">
    <label for="someDate">Some Date</label>
    <input tabindex="2"
           type="tel"
           class="form-control"
           maxlength="7"
           placeholder="MM/YY"
           formControlName="someDate"
           name="someDate"
           [(ngModel)]="fooObj.someDate"
           someDate>
  </div>

但是,我在这个字段上有someDate指令.该指令拦截粘贴事件.它取消了粘贴事件,对输入进行了一些奇特的格式化,然后执行此操作:

setTimeout(() => {
  this.target.value = 'lol fancy date';
},3000);

target.value是我的someDate字段.值在输入框内得到了很好的更新(我看到它在输入内的屏幕上发生了变化).但是,不更新fooObj.someDate并且不会进行验证.例如.在超时中设置目标值不会触发与键入/粘贴/任何其他javascript事件相同的验证/对象更新.

Angular docs对此没什么用处:

Angular updates the bindings (and therefore the screen) only if the app does something in response to asynchronous events,such as keystrokes. This example code binds the keyup event to the number 0,the shortest template statement possible. While the statement does nothing useful,it satisfies Angular’s requirement so that Angular will update the screen.

那么,如何从该字段的指令触发字段更新?

编辑:我尝试使用我的元素上的代码How can I trigger an onchange event manually?,在评论中推荐的元素上触发事件

运行正常,但不强制该字段更新:

if ("createEvent" in document) {
    var evt = document.createEvent("HTMLEvents");
    evt.initEvent("change",false,true);
    this.target.dispatchEvent(evt);
  }
  else
    this.target.fireEvent("onchange");

此外,这里是我得到合成事件的想法,不会触发“正常”行为作为keyDown或任何会(我真的希望我误读或他们错误的这个用例,但它不适用于尝试重新发布粘贴事件):https://www.w3.org/TR/clipboard-apis/#clipboard-event-interfaces

NOTE:
Synthetic events do not have default actions. In other words,while the script above will fire a paste event,the data will not actually be pasted into the document.

解决方法

我不知道你的指令的细节,但我可以猜测你的意图.首先,我们将订阅我们控件的valueChanges observable并直接在控件上避开双向绑定,以避免过多的写入和检查:

form.html

<input tabindex="2"
             type="tel"
             class="form-control"
             maxlength="7"
             placeholder="MM/YY"
             formControlName="someDate"
             name="someDate"
             someDate />

form.ts

这是我们订阅的地方(它可以移出构造函数,取决于您何时制作表单).

constructor() {
    this.myForm = new FormGroup({
        someDate: new FormControl(''),});

    this.myForm.controls['someDate'].valueChanges.subscribe(
      value => this.fooObj.someDate = value;
      );
  }

一些-date.directive.ts

该指令将值写入控件,然后对valueChanges的订阅将更新我们的模型.这适用于粘贴事件和所有其他事件(因此您可以限制目标事件,但我想至少确保粘贴工作).

@Directive({
  selector: '[someDate]'
})
export class SomeDateDirective{
  constructor(private el: ElementRef,private control : NgControl) {

  }

  @HostListener('input',['$event']) onEvent($event){
    $event.preventDefault();
    let data = $event.clipboardData.getData('text');
    setTimeout(() => {
      this.control.control.setValue(data.toupperCase());
    },3000);
  }
}

更改为粘贴而不是输入以仅捕获onpaste事件.使用preventDefault()有点奇怪,因为输入有效地消失了一段时间.

这是一个吸烟者:http://plnkr.co/edit/hsisILvtKErBBOXECt8t?p=preview

原文地址:https://www.jb51.cc/js/157828.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐