इनपुट के एक विशेष चरित्र को बदलने की कोशिश करते हुए, मैंने यह सरल निर्देश लिखना समाप्त कर दिया:

सामान्यीकृत-input.directive.ts

@Directive({
  selector: "[appNormalizedInput]"
})
export class NormalizedInputDirective {
  constructor(private element: ElementRef) {}

  @HostListener("keypress", ["$event"]) replaceAWithB(event): void {
    const initalValue: string = this.element.nativeElement.value;
    this.element.nativeElement.value = initalValue.replace("a", "b");
  }
}

यह कीप्रेस पर a को b से बदल देता है। यह रहा मेरा नमूना (StackBlitz):

app.component.html

<input type="text" (input)="onInput($event)" [(ngModel)]="model" (ngModelChange)="onModelChange()" appNormalizedInput/>
<br/>
<label>{{model}}</label>

app.component.ts

export class AppComponent {
  model = "";

  onInput(event) {
    console.log("on input: ", event.target.value);
  }

  onModelChange() {
    console.log("On model change: ", this.model);
  }
}

एक बार जब मैं a दर्ज करता हूं, तो मैं कंसोल आउटपुट में b की अपेक्षा करता हूं और model (लेबल सामग्री) के लिए भी ऐसा ही करता हूं, लेकिन अगली कुंजी दबाए जाने तक मुझे a मिलता है। समस्या यह है कि ईवेंट one step behind इनपुट का वास्तविक UI मान है।

इस परिदृश्य को संभालने के लिए सही होस्ट लिस्टनर इवेंट क्या है? और मुझे मूल्य कैसे बदलना चाहिए ताकि मैं (input) और (ngModelChange) ईवेंट में नया प्राप्त कर सकूं?

स्टैकब्लिट्ज

3
Efe 18 पद 2020, 05:49

2 जवाब

सबसे बढ़िया उत्तर

आपको ngControl का उपयोग करना चाहिए और अपने इच्छित प्रॉक्सी फ़ंक्शन के साथ onChange ईवेंट को निम्नानुसार लपेटना चाहिए:

@Directive({
  selector: "[myDirective]"
})
export class Mydirective {
  constructor(private ngControl: NgControl) {}

  ngOnInit() {
    const initialOnChange = (this.ngControl.valueAccessor as any).onChange;

    (this.ngControl.valueAccessor as any).onChange = value =>
      initialOnChange(this.processInput(value));
  }

  processInput(value: any) {
    return value.replace("a", "b");
  }

  @HostListener("ngModelChange", ["$event"])
  ngModelChange(value: any) {
    this.ngControl.valueAccessor.writeValue(this.processInput(value));
  }
}

स्टैकब्लिट्ज

1
Nima Afzal 23 पद 2020, 23:40

यदि आप अभी भी इसे keypress ईवेंट को हैंडल करके करना चाहते हैं और टाइप करते समय कर्सर की स्थिति को सुरक्षित रखना चाहते हैं तो आप इस विकल्प को आज़मा सकते हैं:

@HostListener("keypress", ["$event"]) replaceAWithB(e): void {
  if (e.key === 'a') {
    const { selectionStart: start, selectionEnd: end, value: oldValue } = e.target;

    e.target.value = oldValue.slice(0, start) + 'b' + oldValue.slice(end);
    e.target.selectionStart = e.target.selectionEnd = start + 1;

    e.preventDefault();
    e.target.dispatchEvent(new KeyboardEvent('input'));
  }
}

फोर्कड स्टैकब्लिट्ज

1
yurzui 23 पद 2020, 23:47