दिलचस्प पोस्ट
कैसे php के साथ कर्ल का उपयोग कर फ़ाइल अपलोड करें ग्रहण: बाहरी जार के साथ निष्पादन योग्य जार कैसे बनाया जाए? विंडो प्रदर्शित किए बिना PowerShell स्क्रिप्ट को कैसे चलाएं? इकाई ढांचे, संबंधित वस्तुओं को अपडेट करने में समस्याएं क्या Xcode 5 पर आईओएस 6 एसडीके स्थापित करना संभव है? एचटीएमएल पेज को गतिशील रूप से jQuery में डिवेल में लोड करें सिस्टम होस्टनाम प्राप्त करने के लिए मैं कैसे पायथन का उपयोग कर सकता हूं? जावास्क्रिप्ट स्ट्रिंग एक ऑब्जेक्ट नहीं है? सी प्रोग्रामिंग में शून्य सूचक की अवधारणा यदि इनपुट टैग का कोई नाम नहीं है, तो फॉर्म डेटा अभी भी स्थानांतरित हो जाता है? धागा संदर्भ स्विच बनाम प्रक्रिया संदर्भ स्विच बूटस्ट्रैप 3 ग्रिड, क्या यह * वास्तव में * करता है कि कितने कॉलम एक पंक्ति में हैं? जेटेबल सेल में छवि कैसे डालें क्या अजगर के ज़िप () के बराबर जावा है? क्या फोंट iPhone अनुप्रयोगों का समर्थन करते हैं?

कोणीय और बहस

AngularJS में मैं एनजी-मॉडल विकल्प का उपयोग करके एक मॉडल को डिबेंस कर सकता हूं।

ng-model-options="{ debounce: 1000 }" 

मैं कोणीय में एक मॉडल कैसे हटा सकता हूं? मैंने डॉक्स में डिबेंस की खोज करने की कोशिश की लेकिन मुझे कुछ नहीं मिला।

https://angular.io/search/#stq=debounce&stp=1

उदाहरण के लिए, अपना खुद का डेबंस फ़ंक्शन लिखना एक समाधान होगा:

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

और मेरे एचटीएमएल

 <input type=text [value]="firstName" #first (keyup)="firstNameChanged($event, first)"> 

लेकिन मैं फ़ंक्शन में एक बिल्ड की तलाश कर रहा हूं, क्या कोई अंगुलर में है?

Solutions Collecting From Web of "कोणीय और बहस"

आरसी 5 के लिए अद्यतन

कोणीय 2 के साथ हम आरएक्सजेएस ऑपरेटर डिबंसटाइम debounceTime() को एक फॉर्म नियंत्रण के valueChanges सकते हैं।

 import {Component} from '@angular/core'; import {FormControl} from '@angular/forms'; import {Observable} from 'rxjs/Observable'; import 'rxjs/add/operator/debounceTime'; import 'rxjs/add/operator/throttleTime'; import 'rxjs/add/observable/fromEvent'; @Component({ selector: 'my-app', template: `<input type=text [value]="firstName" [formControl]="firstNameControl"> <br>{{firstName}}` }) export class AppComponent { firstName = 'Name'; firstNameControl = new FormControl(); ngOnInit() { // debounce keystroke events this.firstNameControl.valueChanges .debounceTime(1000) .subscribe(newValue => this.firstName = newValue); // throttle resize events Observable.fromEvent(window, 'resize') .throttleTime(200) .subscribe(e => { console.log('resize event', e); this.firstName += '*'; // change something to show it worked }); } ngDoCheck() { console.log('change detection'); } } 

Plunker

ऊपर दिए गए कोड में उदाहरण दिए गए हैं कि कैसे विंडो आकार बदलने की घटनाओं को थ्रॉटल करना है, जैसा कि नीचे टिप्पणी में @albanx ने पूछा था।


यद्यपि उपरोक्त कोड संभवत: ऐसा करने का कोणीय तरीका है, यह कुशल नहीं है प्रत्येक कीस्ट्रोक और हर आकार की घटना, भले ही वे debounced और throttled हैं, परिवर्तन का पता लगाने चलने में परिणाम दूसरे शब्दों में, डीब्यूसिंग और थ्रॉटलिंग से पता चलता है कि कितनी बार पहचान पता चलता है । (मुझे टोबीस बॉश द्वारा एक गिटहब टिप्पणी मिली जो इस बात की पुष्टि करती है।) जब आप प्लंकर चलाते हैं तो आप इसे देख सकते हैं और आप देख सकते हैं कि जब आप इनपुट बॉक्स में टाइप करते हैं या विंडो का आकार ngDoCheck() को कितनी बार बुलाया जा रहा है (आकार बदलने की घटनाओं को देखने के लिए एक अलग विंडो में plunker चलाने के लिए नीले "x" बटन का उपयोग करें।)

एक और अधिक कुशल तकनीक बनाने के लिए आरजेएसजेएस ने अपने आप को घटनाओं से, अंगुलर के "क्षेत्र" के बाहर बना दिया है। इस तरह, परिवर्तन की पहचान प्रत्येक बार एक घटना आग बुलाया नहीं है। उसके बाद, आपके सदस्यता कॉलबैक विधियों में, मैन्युअल रूप से परिवर्तन का पता लगाने के लिए ट्रिगर होता है – यानी, जब आप नियंत्रण का पता लगाते हैं तो आप नियंत्रण करते हैं:

 import {Component, NgZone, ChangeDetectorRef, ApplicationRef, ViewChild, ElementRef} from '@angular/core'; import {Observable} from 'rxjs/Observable'; import 'rxjs/add/operator/debounceTime'; import 'rxjs/add/operator/throttleTime'; import 'rxjs/add/observable/fromEvent'; @Component({ selector: 'my-app', template: `<input #input type=text [value]="firstName"> <br>{{firstName}}` }) export class AppComponent { firstName = 'Name'; @ViewChild('input') inputElRef: ElementRef; constructor(private ngzone: NgZone, private cdref: ChangeDetectorRef, private appref: ApplicationRef) {} ngAfterViewInit() { this.ngzone.runOutsideAngular( () => { Observable.fromEvent(this.inputElRef.nativeElement, 'keyup') .debounceTime(1000) .subscribe(keyboardEvent => { this.firstName = keyboardEvent.target.value; this.cdref.detectChanges(); }); Observable.fromEvent(window, 'resize') .throttleTime(200) .subscribe(e => { console.log('resize event', e); this.firstName += '*'; // change something to show it worked this.cdref.detectChanges(); }); }); } ngDoCheck() { console.log('cd'); } } 

Plunker

मैं ngAfterViewInit() बजाय ngOnInit() का उपयोग करने के लिए यह सुनिश्चित करने के लिए कि inputElRef परिभाषित है

detectChanges() इस घटक और इसके बच्चों पर परिवर्तन का पता चला जाएगा। यदि आप रूट घटक (या तो, एक पूर्ण परिवर्तन पता चला जांच) से परिवर्तन का पता चला तो इसके बजाय ApplicationRef.tick() उपयोग करें। (मैं plunker में टिप्पणियों में ApplicationRef.tick() को एक कॉल डालता हूं।) ध्यान दें कि कॉलिंग tick() को ngDoCheck() कहा जायेगा।

यदि आप @angular/forms साथ सौदा नहीं करना चाहते @angular/forms , तो आप केवल बदलाव बाइंडिंग के साथ एक आरएक्सजेएस Subject उपयोग कर सकते हैं।

view.component.html

 <input [ngModel]='model' (ngModelChange)='changed($event)' /> 

view.component.ts

 import { Subject } from 'rxjs/Subject'; import { Component } from '@angular/core'; import 'rxjs/add/operator/debounceTime'; export class ViewComponent { model: string; modelChanged: Subject<string> = new Subject<string>(); constructor() { this.modelChanged .debounceTime(300) // wait 300ms after the last event before emitting last event .distinctUntilChanged() // only emit if value is different from previous value .subscribe(model => this.model = model); } changed(text: string) { this.modelChanged.next(text); } } 

यह परिवर्तन का पता लगाने ट्रिगर करता है एक तरीका है जो परिवर्तन का पता लगाने को ट्रिगर नहीं करता है, मार्क का उत्तर देखें।

Angular1 में सीधे पहुंच योग्य नहीं है लेकिन आप आसानी से NgFormControl और RxJS अवलोकन के साथ खेल सकते हैं:

 <input type="text" [ngFormControl]="term"/> this.items = this.term.valueChanges .debounceTime(400) .distinctUntilChanged() .switchMap(term => this.wikipediaService.search(term)); 

यह ब्लॉग पोस्ट स्पष्ट रूप से बताता है: http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html

यहां यह एक स्वत: पूर्णता के लिए है लेकिन यह सभी परिदृश्यों को काम करता है

मैंने डेबंस डायरेक्टिव को थोड़ा सा साफ़ कर दिया

 import { Directive, Input, Output, EventEmitter } from '@angular/core'; import { NgControl } from '@angular/forms'; @Directive({ selector: '[ngModel][debounce]', }) export class DebounceDirective { @Output() public onDebounce = new EventEmitter<any>(); @Input('debounce') public debounceTime: number = 500; private isFirstChange: boolean = true; constructor(public model: NgControl) { } ngOnInit() { this.model.valueChanges .debounceTime(this.debounceTime) .distinctUntilChanged() .subscribe(modelValue => { if (this.isFirstChange) { this.isFirstChange = false; } else { this.onDebounce.emit(modelValue); } }); } } 

इसे इस्तेमाल करना पसंद करें

 <input [(ngModel)]="model" [debounce]="500" (onDebounce)="doSomethingWhenModelIsChanged()"> 

किसी को भी रद्दी का उपयोग करने के लिए, किसी भी फ़ंक्शन को रद्द करना बेहद आसान है:

 changed = _.debounce(function() { console.log("name changed!"); }, 400); 

तो बस अपने टेम्पलेट में इस तरह कुछ फेंक:

 <input [ngModel]="firstName" (ngModelChange)="changed()" /> 

सरल उपाय एक निर्देश बनाने के लिए होगा, जिसे आप किसी भी नियंत्रण में लागू कर सकते हैं।

 import { Directive, ElementRef, Input, Renderer, HostListener, Output, EventEmitter } from '@angular/core'; import { NgControl } from '@angular/forms'; @Directive({ selector: '[ngModel][debounce]', }) export class Debounce { @Output() public onDebounce = new EventEmitter<any>(); @Input('debounce') public debounceTime: number = 500; private modelValue = null; constructor(public model: NgControl, el: ElementRef, renderer: Renderer) { } ngOnInit() { this.modelValue = this.model.value; if (!this.modelValue) { var firstChangeSubs = this.model.valueChanges.subscribe(v => { this.modelValue = v; firstChangeSubs.unsubscribe() }); } this.model.valueChanges .debounceTime(this.debounceTime) .distinctUntilChanged() .subscribe(mv => { if (this.modelValue != mv) { this.modelValue = mv; this.onDebounce.emit(mv); } }); } } 

उपयोग होगा

 <textarea [ngModel]="somevalue" [debounce]="2000" (onDebounce)="somevalue = $event" rows="3"> </textarea> 

मैंने इसे एक डेवन डेकोरेटर लिखकर हल किया वर्णित समस्या @debounceAccessor को संपत्ति के सेट एक्सेसर को लागू करने से हल किया जा सकता है।

मैंने विधियों के लिए अतिरिक्त डेवन डेकोरेटर की आपूर्ति की है, जो अन्य अवसरों के लिए उपयोगी हो सकता है।

यह एक संपत्ति या एक विधि को हटा देना बहुत आसान बनाता है पैरामीटर, मिलिसेकंड की संख्या है, जो नीचे दिए गए उदाहरण में 100 मीटर की दूरी पर रहना चाहिए।

 @debounceAccessor(100) set myProperty(value) { this._myProperty = value; } @debounceMethod(100) myMethod (a, b, c) { let d = a + b + c; return d; } 

और यहां सज्जाकारों के लिए कोड दिया गया है:

 function debounceMethod(ms: number, applyAfterDebounceDelay = false) { let timeoutId; return function (target: Object, propName: string, descriptor: TypedPropertyDescriptor<any>) { let originalMethod = descriptor.value; descriptor.value = function (...args: any[]) { if (timeoutId) return; timeoutId = window.setTimeout(() => { if (applyAfterDebounceDelay) { originalMethod.apply(this, args); } timeoutId = null; }, ms); if (!applyAfterDebounceDelay) { return originalMethod.apply(this, args); } } } } function debounceAccessor (ms: number) { let timeoutId; return function (target: Object, propName: string, descriptor: TypedPropertyDescriptor<any>) { let originalSetter = descriptor.set; descriptor.set = function (...args: any[]) { if (timeoutId) return; timeoutId = window.setTimeout(() => { timeoutId = null; }, ms); return originalSetter.apply(this, args); } } } 

मैंने विधि डेकोरेटर के लिए एक अतिरिक्त पैरामीटर जोड़ा है जो डेबंस विलंब के बाद विधि को ट्रिगर करने देता है। मैंने ऐसा किया था, उदाहरण के लिए जब मैं माउसओवर के साथ युग्मित हो या घटनाओं का आकार बदलता हूं, जहां मैं ईवेंट स्ट्रीम के अंत में कैप्चरिंग करना चाहता था। इस मामले में हालांकि, विधि एक मान वापस नहीं करेगा।

आप एक आरएक्सजेएस अवलोकन योग्य बना सकते हैं जो आपको पसंद करता है।

view.component.html

 <input type="text" (input)="onSearchChange($event.target.value)" /> 

view.component.ts

 import { Observable } from 'rxjs/Observable'; export class ViewComponent { searchChangeObserver; onSearchChange(searchValue: string) { if (!this.searchChangeObserver) { Observable.create(observer => { this.searchChangeObserver = observer; }).debounceTime(300) // wait 300ms after the last event before emitting last event .distinctUntilChanged() // only emit if value is different from previous value .subscribe(console.log); } this.searchChangeObserver.next(searchValue); } } 

इस पर वक्त बिताए, उम्मीद है कि मैं किसी और को कुछ समय बचा सकता हूं। मेरे लिए नियंत्रण पर debounce का उपयोग करने के लिए निम्नलिखित दृष्टिकोण अधिक सहज और मेरे लिए समझने में आसान है यह स्वत: पूर्ण करने के लिए angular.io डॉक्स समाधान पर बनाया गया है लेकिन मुझे DOM को डेटा बांधने पर निर्भर होने के बिना कॉलों को अवरुद्ध करने की क्षमता के साथ।

Plunker

इसके लिए उपयोग केस परिदृश्य उपयोगकर्ता को पहले ही ले जाया गया है या नहीं, फिर उपयोगकर्ता को चेतावनी देने के लिए टाइप किए जाने के बाद उपयोगकर्ता नाम की जांच कर सकता है।

ध्यान दें: मत भूलो, (blur)="function(something.value) आपकी आवश्यकताओं के आधार पर आपके लिए अधिक समझ सकता है

एनालर v2 (नवीनतम) प्लस v4 के तहत रिएक्टिव फॉर्म और हैंडलिंग के लिए:

https://github.com/angular/angular/issues/6895#issuecomment-290892514

उम्मीद है कि इन प्रकार की चीजों के लिए मूल समर्थन जल्द ही होगा …