কৌণিক এবং আত্মপ্রকাশ


160

অ্যাঙ্গুলারজেএস-এ আমি এনজি-মডেল বিকল্পগুলি ব্যবহার করে একটি মডেল ডাবোব করতে পারি।

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

তবে আমি একটি বিল্ড ইন ফাংশনটি খুঁজছি, কৌণিকের মধ্যে একটি আছে?


3
এটি প্রাসঙ্গিক github.com/angular/angular/issues/1773 হতে পারে , আপাতদৃষ্টিতে ইমপ্লান্ট করা হয়নি।
এরিক মার্টিনেজ

উত্তর:


202

আরসি 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();
  formCtrlSub: Subscription;
  resizeSub:   Subscription;
  ngOnInit() {
    // debounce keystroke events
    this.formCtrlSub = this.firstNameControl.valueChanges
      .debounceTime(1000)
      .subscribe(newValue => this.firstName = newValue);
    // throttle resize events
    this.resizeSub = 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'); }
  ngOnDestroy() {
    this.formCtrlSub.unsubscribe();
    this.resizeSub  .unsubscribe();
  }
} 

Plunker

উপরের কোডটিতে কীভাবে উইন্ডো রাইজিং ইভেন্টগুলি থ্রোটল করা যায় তার একটি উদাহরণ অন্তর্ভুক্ত রয়েছে, যেমন নীচে একটি মন্তব্যে @ অ্যালবানেক্স জিজ্ঞাসা করেছিলেন।


যদিও উপরের কোডটি সম্ভবত এটি করার কৌণিক উপায়, এটি কার্যকর নয়। প্রতিটি কী-স্ট্রোক এবং প্রতিটি আকার পরিবর্তনকারী ইভেন্ট, যদিও এগুলি উদ্বোধন করা হয় এবং থ্রোটলড হয়, এর ফলে পরিবর্তন সনাক্তকরণ চলমান হয়। অন্য কথায়, ডিবেউনিং এবং থ্রোটলিং কত সময় পরিবর্তন সনাক্ত করে তা চালায় না । (আমি একটি পাওয়া GitHub মন্তব্য যে এই নিশ্চিত করে Tobias বশ দ্বারা।) আপনি এটি দেখতে পারেন যখন আপনি plunker চালাতে এবং আপনি দেখতে কতবার ngDoCheck()যখন আপনি ইনপুট বাক্সে টাইপ করুন অথবা উইন্ডোতে মাপ পরিবর্তন নামক হচ্ছে। (পুনরায় আকারের ইভেন্টগুলি দেখতে পৃথক উইন্ডোতে প্লঙ্কার চালনার জন্য নীল "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';
  keyupSub:  Subscription;
  resizeSub: Subscription;
  @ViewChild('input') inputElRef: ElementRef;
  constructor(private ngzone: NgZone, private cdref: ChangeDetectorRef,
    private appref: ApplicationRef) {}
  ngAfterViewInit() {
    this.ngzone.runOutsideAngular( () => {
      this.keyupSub = Observable.fromEvent(this.inputElRef.nativeElement, 'keyup')
        .debounceTime(1000)
        .subscribe(keyboardEvent => {
          this.firstName = keyboardEvent.target.value;
          this.cdref.detectChanges();
        });
      this.resizeSub = 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'); }
  ngOnDestroy() {
    this.keyupSub .unsubscribe();
    this.resizeSub.unsubscribe();
  }
} 

Plunker

এটি সংজ্ঞায়িত হয়েছে তা নিশ্চিত করার ngAfterViewInit()পরিবর্তে আমি ব্যবহার করি ।ngOnInit()inputElRef

detectChanges()এই উপাদান এবং এর শিশুদের জন্য পরিবর্তন সনাক্তকরণ চালাবে। আপনি যদি এর পরিবর্তে মূল উপাদান থেকে পরিবর্তন সনাক্তকরণ চালাতে চান (যেমন, একটি সম্পূর্ণ পরিবর্তন সনাক্তকরণ চেক চালান) তবে তার ApplicationRef.tick()পরিবর্তে ব্যবহার করুন। (আমি ApplicationRef.tick()প্লাঙ্কারের মন্তব্যে একটি কল দিয়েছি)) নোট করুন যে কলিং কল করার tick()কারণ হবে ngDoCheck()


2
@ মার্ক রাজকোক আমার মনে হয় [মান] এর পরিবর্তে আপনার [এনজি মডেল] ব্যবহার করা উচিত, কারণ [মান] ইনপুট মান আপডেট করে না।
মিলাদ

1
কোন জেনেরিক আত্মপ্রকাশ পদ্ধতি আছে (উদাহরণস্বরূপ উইন্ডো আকার পরিবর্তন ইভেন্টে প্রয়োগ করতে)?
albanx

1
@ মারকরাজাকোক আমি বিশ্বাস করি যে আপনি নিজের উত্তরে বর্ণিত সিডি সমস্যাটি github.com/angular/zone.js/pull/843
জেফটপিয়া

2
মেমরি ফাঁস রোধ করতে কখন আমাদের সদস্যতা বাতিল করতে হবে?
অপবাদ 17

1
@ স্ল্যান্ডেন হ্যাঁ, নেটবাসাল. com / When- to- unsubscribe-in-angular-d61c6b21bad3 অনুসারে , আমাদের সাবস্ক্রিপশন থেকে .fromEvent()সাবস্ক্রাইব করা উচিত
জন অনস্টট

153

আপনি যদি ডিল করতে না চান @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);
    }
}

এটি ট্রিগার পরিবর্তন সনাক্তকরণ করে। এমন একটি উপায় যাতে পরিবর্তন সনাক্তকরণকে ট্রিগার করে না, মার্কের উত্তরটি দেখুন।


হালনাগাদ

.pipe(debounceTime(300), distinctUntilChanged()) rxjs 6 এর জন্য প্রয়োজন।

উদাহরণ:

   constructor() {
        this.modelChanged.pipe(
            debounceTime(300), 
            distinctUntilChanged())
            .subscribe(model => this.model = model);
    }

5
আমি এই সমাধান পছন্দ! কৌনিক 2.0.0, rxjs 5.0.0-বিটা 12
alsco77

2
নিখুঁত, সহজ এবং পরিষ্কার, কোন রূপ জড়িত কাজ করেছেন। আমি কৌনিক 4.1.3 এ আছি, rxjs 5.1.1
পঞ্চম

আমি মনে করি এটি সর্বোত্তম সমাধান কারণ এটির জন্য প্রয়োজনে ফর্মগুলির সাথে কাজ করার বিকল্প রয়েছে তবে এটি নির্ভরতা বাস্তবায়নকে এত সহজ করে তোলে। ধন্যবাদ।
সর্বাধিক

2
.pipe(debounceTime(300), distinctUntilChanged())rxjs 6 এর জন্য প্রয়োজন
আইসাইকুল

সমাধান আমাকে বাঁচায়। আমি ব্যবহার করছিলেন keyUpএর ইভেন্টে input.nativeElementএকটি mat-table, যে কাজ করা বন্ধ করে যখন কলামের সংখ্যা পরিবর্তন করা হয়েছে
igorepst

35

এটি দিকনির্দেশক হিসাবে প্রয়োগ করা যেতে পারে

import { Directive, Input, Output, EventEmitter, OnInit, OnDestroy } from '@angular/core';
import { NgControl } from '@angular/forms';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import { Subscription } from 'rxjs';

@Directive({
  selector: '[ngModel][onDebounce]',
})
export class DebounceDirective implements OnInit, OnDestroy {
  @Output()
  public onDebounce = new EventEmitter<any>();

  @Input('debounce')
  public debounceTime: number = 300;

  private isFirstChange: boolean = true;
  private subscription: Subscription;

  constructor(public model: NgControl) {
  }

  ngOnInit() {
    this.subscription =
      this.model.valueChanges
        .debounceTime(this.debounceTime)
        .distinctUntilChanged()
        .subscribe(modelValue => {
          if (this.isFirstChange) {
            this.isFirstChange = false;
          } else {
            this.onDebounce.emit(modelValue);
          }
        });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

}

এটি পছন্দ করুন

<input [(ngModel)]="value" (onDebounce)="doSomethingWhenModelIsChanged($event)">

উপাদান নমুনা

import { Component } from "@angular/core";

@Component({
  selector: 'app-sample',
  template: `
<input[(ngModel)]="value" (onDebounce)="doSomethingWhenModelIsChanged($event)">
<input[(ngModel)]="value" (onDebounce)="asyncDoSomethingWhenModelIsChanged($event)">
`
})
export class SampleComponent {
  value: string;

  doSomethingWhenModelIsChanged(value: string): void {
    console.log({ value });
  }

  async asyncDoSomethingWhenModelIsChanged(value: string): Promise<void> {
    return new Promise<void>(resolve => {
      setTimeout(() => {
        console.log('async', { value });
        resolve();
      }, 1000);
    });
  }
} 

1
আরও আমদানি সহ, যা আমার পক্ষে কাজ করেছে: "rxjs / add / অপারেটর / ডিবাউশনটাইম" আমদানি করুন; "আরএক্সজেএস / অ্যাড / অপারেটর / স্বতন্ত্র-পরিবর্তন" আমদানি করুন;
এসবিএল

2
এটি এতদূর পর্যন্ত অ্যাপ্লিকেশনটিকে প্রশস্ত করে
তুলতে

1
isFirstChange প্রারম্ভকালীন নির্গত করতে ব্যবহার করা হয় না
ওলেগ পোলেজকি

2
কৌনিক 8 এবং rxjs 6.5.2 এ নিম্নলিখিত পরিবর্তনগুলির সাথে কাজ করে। : আপনি পাইপ সিনট্যাক্স ব্যবহার করতে চান তাহলে, নিম্নলিখিত পরিবর্তন import 'rxjs/add/operator/debounceTime'; import 'rxjs/add/operator/distinctUntilChanged';করার জন্য import { debounceTime, distinctUntilChanged } from 'rxjs/operators';এবং this.model.valueChanges .debounceTime(this.debounceTime) .distinctUntilChanged()জন্যthis.model.valueChanges .pipe( debounceTime(this.debounceTime), distinctUntilChanged() )
kumaheiyama

1
কৌনিক 9 এবং rxjs 6.5.4 এ কাজ করে @ kumaheiyama পরিবর্তন করে তার মন্তব্যে জানিয়েছে। আপনি যে মডিউলটি তৈরি করছেন সেখানে কেবল নির্দেশটি রফতানি করতে ভুলবেন না। আপনি যে মডিউলটি এটি পরিচালনা করছেন সেখানে যে মডিউলটি আপনি এটি ব্যবহার করছেন সেখানে অন্তর্ভুক্ত করতে ভুলবেন না।
ফিলিপ সাভিক

29

যেহেতু বিষয় পুরানো, উত্তর অধিকাংশ কাজ করে না উপর কৌণিক 6/7/8/9 এবং / অথবা অন্যান্য লিব ব্যবহার করুন।
সুতরাং এখানে RxJS সহ কৌণিক 6+ এর জন্য একটি সংক্ষিপ্ত এবং সহজ সমাধান।

প্রথমে প্রয়োজনীয় জিনিসগুলি আমদানি করুন:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subject, Subscription } from 'rxjs';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';

শুরু করুন ngOnInit:

export class MyComponent implements OnInit, OnDestroy {
  public notesText: string;
  private notesModelChanged: Subject<string> = new Subject<string>();
  private notesModelChangeSubscription: Subscription

  constructor() { }

  ngOnInit() {
    this.notesModelChangeSubscription = this.notesModelChanged
      .pipe(
        debounceTime(2000),
        distinctUntilChanged()
      )
      .subscribe(newText => {
        this.notesText = newText;
        console.log(newText);
      });
  }

  ngOnDestroy() {
    this.notesModelChangeSubscription.unsubscribe();
  }
}

এইভাবে ব্যবহার করুন:

<input [ngModel]='notesText' (ngModelChange)='notesModelChanged.next($event)' />

PS: আরও জটিল এবং দক্ষ সমাধানের জন্য আপনি এখনও অন্য উত্তরগুলি পরীক্ষা করতে চাইতে পারেন।


1
কেন আপনি এটি ধ্বংসের উপর সাবস্ক্রাইব করবেন না?
বীরেন্দ্র সিং রাঠোর

আপডেট করা হয়েছে। দেখার জন্য ধন্যবাদ!
জাস্ট শেডো

1
@ জাস্টশাডো ধন্যবাদ! এটা সত্যিই সহায়ক ছিল।
নিরাল মুঞ্জারিয়া

এটি প্রথম চেষ্টাতে নিখুঁত কাজ করে। তবে যখন আমি কোনওভাবে অনুসন্ধান করা পাঠ্যটি মুছব তখন পরবর্তী অনুরোধটি সাড়া দিতে খুব বেশি সময় নেয়।
সাদিকশা গৌতম

এটা অদ্ভুত. এটি আমার পক্ষে এখনও ঠিক কাজ করে। আপনি কি আরও তথ্য ভাগ করতে পারেন বা সম্ভবত এটির জন্য একটি নতুন প্রশ্ন খুলতে পারেন?
মাত্র ছায়া

28

কৌণিক 1 এর মতো সরাসরি অ্যাক্সেসযোগ্য নয় তবে আপনি সহজেই এনজিএফর্মকন্ট্রোল এবং আরএক্সজেএস পর্যবেক্ষণের সাথে খেলতে পারেন:

<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- લાભage-of-observables-in-angular2.html

এখানে এটি একটি স্ব-পরিপূর্ণের জন্য তবে এটি সমস্ত পরিস্থিতিতে কাজ করে।


তবে পরিষেবা থেকে একটি ত্রুটি রয়েছে, এটি আবার চলবে না
অরুণ তায়াগি

আমি উদাহরণ বুঝতে পারি না। [...] একমুখী লক্ষ্য বাঁধাই। কেন ধারক সম্পর্কে অবহিত করা যেতে পারে valueChanges? এটা sth করা উচিত নয়। পছন্দ (ngFormControl)="..."?
phil294

20

আপনি একটি আরএক্সজেএস তৈরি করতে পারেন (v.6) পর্যবেক্ষণযোগ্য যা আপনার যা পছন্দ তা করে।

view.component.html

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

view.component.ts

import { Observable } from 'rxjs';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';

export class ViewComponent {
    searchChangeObserver;

  onSearchChange(searchValue: string) {

    if (!this.searchChangeObserver) {
      Observable.create(observer => {
        this.searchChangeObserver = observer;
      }).pipe(debounceTime(300)) // wait 300ms after the last event before emitting last event
        .pipe(distinctUntilChanged()) // only emit if value is different from previous value
        .subscribe(console.log);
    }

    this.searchChangeObserver.next(searchValue);
  }  


}

ধন্যবাদ সাহায্য করেছে, তবে আমি মনে করি আমদানি থেকে হওয়া উচিত rsjs/Rx, আমি ত্রুটি যখন আমদানি ভাবে আপনি এটা লিখেছে ব্যবহার ... তাই আমার ক্ষেত্রে এটি এখন ছিল:import { Observable } from 'rxjs/Rx';
ghiscoding

2
@ giscoding এটি rxjs সংস্করণের উপর নির্ভর করে। সংস্করণ 6 এটা হল: import { Observable } from 'rxjs';
ম্যাথিয়াস

ধন্যবাদ! সরাইয়া হিসাবে, আপনি কেবল একটি pipeকল ব্যবহার করতে পারেনpipe(debounceTime(300), distinctUntilChanged())
আল।

1
সার্চ চ্যাঞ্জওবার্সার একজন গ্রাহক, তাই অনুসন্ধানচেন্জসবার্সকার আরও ভাল নাম হবে।
খনসোর্ট

12

লোড্যাশ ব্যবহার করা যে কোনও ব্যক্তির জন্য, যে কোনও ক্রিয়াকলাপটি ডাব্যু করা অত্যন্ত সহজ :

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

তারপরে আপনার টেম্পলেটে এই জাতীয় কিছু ফেলে দিন:

<(input)="changed($event.target.value)" />

3
অথবা just (ইনপুট) = "পরিবর্তিত ($ ইভেন্ট.তারেকেট.ভ্যালু)"
জ্যামি কুডলা

1
:) lodash সঙ্গে উত্তর দেওয়ার জন্য আপনাকে ধন্যবাদ
Vamsi

আমি বিশ্বাস করি এটি তবুও নির্বিশেষে প্রতিটি একক পরিবর্তনের উপর কৌণিক পরিবর্তন সনাক্তকরণকে ট্রিগার করবে।
AsGoodAsItGates

5

ইভেন্ট ফাংশনে সরাসরি ইনিশিয়েশন গ্রাহকের সাথে সমাধান:

import {Subject} from 'rxjs';
import {debounceTime, distinctUntilChanged} from 'rxjs/operators';

class MyAppComponent {
    searchTermChanged: Subject<string> = new Subject<string>();

    constructor() {
    }

    onFind(event: any) {
        if (this.searchTermChanged.observers.length === 0) {
            this.searchTermChanged.pipe(debounceTime(1000), distinctUntilChanged())
                .subscribe(term => {
                    // your code here
                    console.log(term);
                });
        }
        this.searchTermChanged.next(event);
    }
}

এবং এইচটিএমএল:

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

কৌনিক 8 প্রাইম এনজি স্বয়ংক্রিয়রূপে পাঠ্যবক্সের জন্য সম্পূর্ণ সূক্ষ্ম কাজ করে। অনেক ধন্যবাদ.
জেসমিন আক্তার সুমা

4

আমি একটি ডেবিউ ডেকরেটর লিখে এটি সমাধান করেছি। সম্পত্তিটির সেট অ্যাকসেসরে @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);
    }
  }
}

আমি পদ্ধতিটি সাজসজ্জার জন্য একটি অতিরিক্ত পরামিতি যুক্ত করেছি যা আসল বিলম্বের পরে আপনি পদ্ধতিটি ট্রিগার করুন। আমি এটি করেছি যাতে আমি উদাহরণস্বরূপ মাউসওভারের সাথে মিলিত বা ইভেন্টগুলি পুনরায় আকার দেওয়ার সাথে সাথে এটি ব্যবহার করতে পারি, যেখানে আমি ইভেন্ট স্ট্রিমের শেষে ক্যাপচারিংটি ঘটতে চাইতাম। তবে এই ক্ষেত্রে, পদ্ধতিটি কোনও মান ফেরত দেবে না।


3

আমরা একটি [ডিবনস] নির্দেশনা তৈরি করতে পারি যা এনজিএমডেলের ডিফল্ট ভিউ টোমোডেল আপডেট ফাংশনকে খালি দিয়ে ওভাররাইট করে।

দিকনির্দেশক কোড

@Directive({ selector: '[debounce]' })
export class MyDebounce implements OnInit {
    @Input() delay: number = 300;

    constructor(private elementRef: ElementRef, private model: NgModel) {
    }

    ngOnInit(): void {
        const eventStream = Observable.fromEvent(this.elementRef.nativeElement, 'keyup')
            .map(() => {
                return this.model.value;
            })
            .debounceTime(this.delay);

        this.model.viewToModelUpdate = () => {};

        eventStream.subscribe(input => {
            this.model.viewModel = input;
            this.model.update.emit(input);
        });
    }
}

এটি কিভাবে ব্যবহার করতে

<div class="ui input">
  <input debounce [delay]=500 [(ngModel)]="myData" type="text">
</div>

2

এইচটিএমএল ফাইল:

<input [ngModel]="filterValue"
       (ngModelChange)="filterValue = $event ; search($event)"
        placeholder="Search..."/>

টিএস ফাইল:

timer = null;
time = 250;
  search(searchStr : string) : void {
    clearTimeout(this.timer);
    this.timer = setTimeout(()=>{
      console.log(searchStr);
    }, time)
  }

2

সহজ সমাধান হ'ল কোনও নির্দেশ তৈরি করা যা আপনি যে কোনও নিয়ন্ত্রণের জন্য প্রয়োগ করতে পারেন।

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>

এই ক্লাসটি সংকলন থেকে অনেক দূরে Angular 7
স্টিফেন

1

এতে কয়েক ঘন্টা সময় ব্যয় করলাম, আশা করি আমি অন্য কাউকে কিছু সময় বাঁচাতে পারব। আমার কাছে debounceএকটি নিয়ন্ত্রণে ব্যবহার করার জন্য নিম্নলিখিত পদ্ধতিটি আমার জন্য আরও স্বজ্ঞাত এবং সহজে বোঝা যায়। এটি স্বতঃসিদ্ধের জন্য কৌণিক.ও ডক্স সমাধানে তৈরি হয়েছে তবে ডমকে ডেটা বেঁধে রাখার উপর নির্ভর না করে কলগুলি আমার কাছে আটকানোর ক্ষমতা দিয়ে।

Plunker

এর জন্য ব্যবহারের পরিস্থিতিটি কোনও ব্যবহারকারীর নাম টাইপ করার পরে এটি ইতিমধ্যে কেউ গ্রহণ করেছে কিনা তা পরীক্ষা করে দেখছে, তারপরে ব্যবহারকারীকে সতর্ক করে।

দ্রষ্টব্য: ভুলে যাবেন না, (blur)="function(something.value)আপনার প্রয়োজনের উপর নির্ভর করে আপনার আরও বোধ করতে পারে।


1

আরএক্সজেএস ভি 6 এর সাথে কৌণিক 7 এ ডিবাউনটাইম

উত্স লিঙ্ক

ডেমো লিঙ্ক

এখানে চিত্র বর্ণনা লিখুন

এইচটিএমএল টেমপ্লেটে

<input type="text" #movieSearchInput class="form-control"
            placeholder="Type any movie name" [(ngModel)]="searchTermModel" />

উপাদান মধ্যে

    ....
    ....
    export class AppComponent implements OnInit {

    @ViewChild('movieSearchInput') movieSearchInput: ElementRef;
    apiResponse:any;
    isSearching:boolean;

        constructor(
        private httpClient: HttpClient
        ) {
        this.isSearching = false;
        this.apiResponse = [];
        }

    ngOnInit() {
        fromEvent(this.movieSearchInput.nativeElement, 'keyup').pipe(
        // get value
        map((event: any) => {
            return event.target.value;
        })
        // if character length greater then 2
        ,filter(res => res.length > 2)
        // Time in milliseconds between key events
        ,debounceTime(1000)        
        // If previous query is diffent from current   
        ,distinctUntilChanged()
        // subscription for response
        ).subscribe((text: string) => {
            this.isSearching = true;
            this.searchGetCall(text).subscribe((res)=>{
            console.log('res',res);
            this.isSearching = false;
            this.apiResponse = res;
            },(err)=>{
            this.isSearching = false;
            console.log('error',err);
            });
        });
    }

    searchGetCall(term: string) {
        if (term === '') {
        return of([]);
        }
        return this.httpClient.get('http://www.omdbapi.com/?s=' + term + '&apikey=' + APIKEY,{params: PARAMS.set('search', term)});
    }

    }

1

আপনি এটি সজ্জকার ব্যবহার করেও সমাধান করতে পারেন, উদাহরণস্বরূপ ইউসেস - ডেকরেটার লাইব ( npm install utils-decorators) থেকে ডেবিউন ডেকোরেশন ব্যবহার করে :

import {debounce} from 'utils-decorators';

class MyAppComponent {

  @debounce(500)
  firstNameChanged($event, first) {
   ...
  }
}

0

এটি এখন অবধি পাওয়া সেরা সমাধান। ngModelচালু blurএবং আপডেট করেdebounce

import { Directive, Input, Output, EventEmitter,ElementRef } from '@angular/core';
import { NgControl, NgModel } from '@angular/forms';
import 'rxjs/add/operator/debounceTime'; 
import 'rxjs/add/operator/distinctUntilChanged';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/map';

@Directive({
    selector: '[ngModel][debounce]',
})
export class DebounceDirective {
    @Output()
    public onDebounce = new EventEmitter<any>();

    @Input('debounce')
    public debounceTime: number = 500;

    private isFirstChange: boolean = true;

    constructor(private elementRef: ElementRef, private model: NgModel) {
    }

    ngOnInit() {
        const eventStream = Observable.fromEvent(this.elementRef.nativeElement, 'keyup')
            .map(() => {
                return this.model.value;
            })
            .debounceTime(this.debounceTime);

        this.model.viewToModelUpdate = () => {};

        eventStream.subscribe(input => {
            this.model.viewModel = input;
            this.model.update.emit(input);
        });
    }
}

https://stackoverflow.com/a/47823960/3955513 থেকে ধার করা হিসাবে

তারপরে এইচটিএমএলে:

<input [(ngModel)]="hero.name" 
        [debounce]="3000" 
        (blur)="hero.name = $event.target.value"
        (ngModelChange)="onChange()"
        placeholder="name">

উপর blurমডেল স্পষ্টভাবে প্লেইন জাভাস্ক্রিপ্ট ব্যবহার আপডেট করা হয়।

উদাহরণ এখানে: https://stackblitz.com/edit/ng2-debounce-king

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.