Update Angular 2 Field Program

I have the following form field that works fine. By this I mean that when I enter, insert, etc. In the field, fooObj.expDate updated just fine in real time and validation happens. I have a preliminary tag to make this obvious to me.

  <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> 

However, I have this someDate directive in this field. This directive captures past events. It cancels the insert event, does some kind of fancy input formatting, and then does the following:

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

target.value is my someDate field. The value becomes updated in the input window (I see that it changes on the screen inside the input). However, fooObj.someDate NOT updated, and verification does not occur. For instance. setting the target value in the timeout does NOT trigger the same check / object update as entering the key / insert / any other javascript event.

Angular docs are not much useful:

Angular updates bindings (and therefore the screen) only if the application does something in response to asynchronous events, such as keystrokes. This sample code associates the keyup event with number 0, the shortest statement of the template is possible. Although the statement does nothing, it satisfies Angular's requirement for Angular to refresh the screen.

So, how do I initiate an update of a field from a directive in this field?

Edit: I tried to fire the event in the element, as recommended in the comments, using the code found here in my element: How can I fire the onchange event manually?

It works fine, but does not force the field to be updated:

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

In addition, here I get an idea of ​​synthetic events that do not cause β€œnormal” actions like keyDown or something like that (I really hope that I misunderstood or they are wrong in this use case, but this is not the work of trying to re insert event release): https://www.w3.org/TR/clipboard-apis/#clipboard-event-interfaces

Note: Synthetic events do not have a default action. In other words, while the script above will fire the insert event, the data will not actually be inserted into the document.

+6
source share
1 answer

I do not know the details of your directive, but I can guess your intentions. To begin with, we are going to subscribe to the valueChanges , which is monitored by our control, and avoid the two-way binding directly to the control to avoid over-writing and validation:

form.html

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

form.ts

Here we subscribe (it can exit the constructor, it depends on when you make the form).

 constructor() { this.myForm = new FormGroup({ someDate: new FormControl(''), }); this.myForm.controls['someDate'].valueChanges.subscribe( value => this.fooObj.someDate = value; ); } 

some-date.directive.ts

The directive will write the value to the control, and subscribing to valueChanges then update our model. This works with the insert event and every other event (so that you can limit the target events, but I wanted to at least make sure that the insert is done).

 @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); } } 

Change to paste instead of input to only display onpaste events. This is a bit strange with preventDefault() , as the input effectively disappears for a while.

Here's the plunker: http://plnkr.co/edit/hsisILvtKErBBOXECt8t?p=preview

+2
source

Source: https://habr.com/ru/post/1012733/


All Articles