In AngularJS kann ich ein Modell mithilfe von ng-model-Optionen entprellen.
ng-model-options="{ debounce: 1000 }"
Wie kann ich ein Modell in Angular entprellen? Ich habe versucht, in den Dokumenten nach Entprellungen zu suchen, konnte aber nichts finden.
https://angular.io/search/#stq=debounce&stp=1
Eine Lösung wäre, meine eigene Entprellungsfunktion zu schreiben, zum Beispiel:
import {Component, Template, bootstrap} from 'angular2/angular2';
// Annotation section
@Component({
selector: 'my-app'
})
@Template({
url: 'app.html'
})
// Component controller
class MyAppComponent {
constructor() {
this.firstName = 'Name';
}
changed($event, el){
console.log("changes", this.name, el.value);
this.name = el.value;
}
firstNameChanged($event, first){
if (this.timeoutId) window.clearTimeout(this.timeoutID);
this.timeoutID = window.setTimeout(() => {
this.firstName = first.value;
}, 250)
}
}
bootstrap(MyAppComponent);
Und mein HTML
<input type=text [value]="firstName" #first (keyup)="firstNameChanged($event, first)">
Aber ich suche nach einer eingebauten Funktion, gibt es eine in Angular?
javascript
angular
koningdavid
quelle
quelle
Antworten:
Aktualisiert für RC.5
Mit Angular 2 können wir mit dem RxJS-Operator
debounceTime()
auf demvalueChanges
Observable eines Formularsteuerelements entprellen :Plunker
Der obige Code enthält auch ein Beispiel für das Drosseln der Größe von Fenstern, wie von @albanx in einem Kommentar unten gefragt.
Obwohl der obige Code wahrscheinlich die Angular-Methode ist, ist er nicht effizient. Jeder Tastendruck und jedes Größenänderungsereignis führt dazu, dass die Änderungserkennung ausgeführt wird, obwohl sie entprellt und gedrosselt werden. Mit anderen Worten, das Entprellen und Drosseln hat keinen Einfluss darauf, wie oft die Änderungserkennung ausgeführt wird . (Ich habe einen GitHub-Kommentar von Tobias Bosch gefunden, der dies bestätigt.) Sie können dies sehen, wenn Sie den Plunker ausführen, und Sie sehen, wie oft
ngDoCheck()
aufgerufen wird, wenn Sie in das Eingabefeld eingeben oder die Fenstergröße ändern. (Verwenden Sie die blaue Schaltfläche "x", um den Plunker in einem separaten Fenster auszuführen und die Größenänderungsereignisse anzuzeigen.)Eine effizientere Technik besteht darin, RxJS Observables selbst aus den Ereignissen außerhalb von Angulars "Zone" zu erstellen. Auf diese Weise wird die Änderungserkennung nicht jedes Mal aufgerufen, wenn ein Ereignis ausgelöst wird. Lösen Sie dann in Ihren Abonnement-Rückrufmethoden die Änderungserkennung manuell aus, dh Sie steuern, wann die Änderungserkennung aufgerufen wird:
Plunker
Ich benutze
ngAfterViewInit()
stattngOnInit()
um sicherzustellen, dassinputElRef
das definiert ist.detectChanges()
führt die Änderungserkennung für diese Komponente und ihre untergeordneten Komponenten aus. Wenn Sie die Änderungserkennung lieber über die Stammkomponente ausführen möchten (dh eine vollständige Änderungserkennungsprüfung durchführen), verwenden SieApplicationRef.tick()
stattdessen. (Ich habeApplicationRef.tick()
in Kommentaren im Plunker einen Anruf getätigt.) Beachten Sie, dass beim Aufruf ein Anruf ausgelösttick()
wirdngDoCheck()
.quelle
.fromEvent()
Abonnements abmeldenWenn Sie sich nicht damit befassen möchten
@angular/forms
, können Sie einfach ein RxJSSubject
mit Änderungsbindungen verwenden.view.component.html
view.component.ts
Dies löst eine Änderungserkennung aus. Lesen Sie Marks Antwort, um eine Möglichkeit zu finden, die keine Änderungserkennung auslöst.
Aktualisieren
.pipe(debounceTime(300), distinctUntilChanged())
wird für rxjs 6 benötigt.Beispiel:
quelle
.pipe(debounceTime(300), distinctUntilChanged())
wird für rxjs 6keyUp
event oninput.nativeElement
in a verwendetmat-table
, das nicht mehr funktioniert, als die Anzahl der Spalten geändert wurdeEs könnte als Richtlinie umgesetzt werden
benutze es wie
Komponentenprobe
quelle
import 'rxjs/add/operator/debounceTime'; import 'rxjs/add/operator/distinctUntilChanged';
toimport { debounceTime, distinctUntilChanged } from 'rxjs/operators';
undthis.model.valueChanges .debounceTime(this.debounceTime) .distinctUntilChanged()
tothis.model.valueChanges .pipe( debounceTime(this.debounceTime), distinctUntilChanged() )
Da das Thema alt ist, funktionieren die meisten Antworten nicht in Angular 6/7/8/9 und / oder verwenden andere Bibliotheken.
Hier ist eine kurze und einfache Lösung für Angular 6+ mit RxJS.
Importieren Sie zuerst das notwendige Material:
Initialisieren am
ngOnInit
:Verwenden Sie diesen Weg:
PS: Für komplexere und effizientere Lösungen möchten Sie möglicherweise noch andere Antworten überprüfen.
quelle
Nicht direkt zugänglich wie in angle1, aber Sie können problemlos mit NgFormControl- und RxJS-Observablen spielen:
Dieser Blog-Beitrag erklärt es klar: http://blog.ehowtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html
Hier ist es für eine automatische Vervollständigung, aber es funktioniert in allen Szenarien.
quelle
[...]
ist eine Einweg-Zielbindung. Warum kann der Container benachrichtigt werdenvalueChanges
? sollte es nicht etw sein müssen wie(ngFormControl)="..."
?Sie können ein RxJS (v.6) Observable erstellen , das macht, was Sie wollen.
view.component.html
view.component.ts
quelle
rsjs/Rx
. Ich hatte Fehler, als ich den Import so verwendete, wie Sie ihn geschrieben haben. In meinem Fall ist es jetzt:import { Observable } from 'rxjs/Rx';
import { Observable } from 'rxjs';
.pipe
Anrufpipe(debounceTime(300), distinctUntilChanged())
Für jeden, der lodash verwendet, ist es extrem einfach, eine Funktion zu entprellen :
dann werfen Sie einfach so etwas in Ihre Vorlage:
quelle
Lösung mit Initialisierungsteilnehmer direkt in der Ereignisfunktion:
Und html:
quelle
Ich habe das gelöst, indem ich einen Debounce-Dekorateur geschrieben habe. Das beschriebene Problem kann gelöst werden, indem der @debounceAccessor auf den festgelegten Accessor der Eigenschaft angewendet wird.
Ich habe auch einen zusätzlichen Debounce-Dekorator für Methoden bereitgestellt, der für andere Gelegenheiten nützlich sein kann.
Dies macht es sehr einfach, eine Eigenschaft oder eine Methode zu entprellen. Der Parameter gibt die Anzahl der Millisekunden an, die das Entprellen dauern soll, im folgenden Beispiel 100 ms.
Und hier ist der Code für die Dekorateure:
Ich habe einen zusätzlichen Parameter für den Methodendekorator hinzugefügt, mit dem Sie die Methode NACH der Entprellungsverzögerung auslösen können. Ich habe das getan, damit ich es beispielsweise in Verbindung mit Mouseover- oder Größenänderungsereignissen verwenden kann, bei denen die Erfassung am Ende des Ereignisstroms erfolgen soll. In diesem Fall gibt die Methode jedoch keinen Wert zurück.
quelle
Wir können eine [entprellen] Direktive erstellen, die die Standardfunktion viewToModelUpdate von ngModel mit einer leeren überschreibt.
Richtliniencode
Wie man es benutzt
quelle
HTML-Datei:
TS-Datei:
quelle
Eine einfache Lösung wäre, eine Direktive zu erstellen, die Sie auf jedes Steuerelement anwenden können.
Nutzung wäre
quelle
Angular 7
.Ich habe Stunden damit verbracht, hoffentlich kann ich jemand anderem etwas Zeit sparen. Für mich ist der folgende Ansatz zur Verwendung
debounce
eines Steuerelements intuitiver und für mich leichter zu verstehen. Es basiert auf der Angular.io Docs-Lösung für die automatische Vervollständigung, bietet mir jedoch die Möglichkeit, die Anrufe abzufangen, ohne die Daten an das DOM binden zu müssen.Plunker
Ein Anwendungsszenario hierfür könnte darin bestehen, einen Benutzernamen nach der Eingabe zu überprüfen, um festzustellen, ob jemand ihn bereits übernommen hat, und dann den Benutzer zu warnen.
Hinweis: Vergessen Sie nicht,
(blur)="function(something.value)
dass dies je nach Ihren Anforderungen für Sie möglicherweise sinnvoller ist.quelle
DebounceTime in Angular 7 mit RxJS v6
Quelle Link -
Demo Link
In der HTML-Vorlage
In Komponente
quelle
Sie können dies auch mithilfe eines Dekorators lösen. Beispiel: Verwenden Sie den Debounce-Dekorator von utils-decorator lib (
npm install utils-decorators
):quelle
Dies ist die beste Lösung, die ich bisher gefunden habe. Aktualisiert die
ngModel
aufblur
unddebounce
wie von https://stackoverflow.com/a/47823960/3955513 ausgeliehen
Dann in HTML:
Das
blur
Modell wird explizit mit einfachem Javascript aktualisiert.Beispiel hier: https://stackblitz.com/edit/ng2-debounce-working
quelle