如何通过javascript中的主题更新传递事件?

时间:2018-03-15 10:59:58

标签: javascript angular typescript javascript-events debounce

我们一直面临将事件从html传递到需要它的javascript方法之一的问题。

export class SearchComponent implements OnInit {
    txtQueryChanged: Subject<string> = new Subject();

    constructor(private AService: AService, public _router: Router, location: PlatformLocation) {

        this.txtQueryChanged.debounceTime(1000)
        .distinctUntilChanged()
        .subscribe(model => {
             this.q = model;
             // Call function which calls API after a lag of 1 sec
             this.getDetails(model);
        });
    }

    watchChangesInSearchTerm(query: string, $event: 
        this.txtQueryChanged.next(query);
    }
    getDetails(event: any) {
        this.eventKey = event.which;
        if (this.q.trim() == "") {
            this.closeSearch();
        }
        // other programming logic including the API call
    }// end of function
}// end of class

现在调用此watchChangesInSearchTerm的HTML如下

<input type="text" class="searchfield" [(ngModel)]="q" name="searchfield"  (keyup)="watchChangesInSearchTerm(q, $event)" placeholder="What are you searching for today?">

现在,HTML中的代码调用了 watchChangesInSearchTerm 方法,但它只传递了searchString int参数。 watchChangesInSearchTerm 依次对模型进行去抖动并调用 getDetails 方法。此方法也被许多其他用例调用,因此需要触发它的事件。

我们如何将事件传递给 getDetails 方法?

提前感谢任何希望提供帮助的人。

2 个答案:

答案 0 :(得分:0)

好吧,我的建议是:

txtQueryChanged: Subject<KeyboardEvent> = new Subject();
constructor(private AService: AService, public _router: Router, location: PlatformLocation) {

    this.txtQueryChanged.debounceTime(1000)
    .distinctUntilChanged()
    .subscribe(event => {
         // this.q = model; --> Not necessary! ngModel already updates q
         // Call function which calls API after a lag of 1 sec
         this.getDetails(event);
    });
}

watchChangesInSearchTerm($event: KeyboardEvent)
    this.txtQueryChanged.next($event);
}

然后,在您的模板中,只需这样做,因为您不需要搜索此问题:

<input type="text" class="searchfield" [(ngModel)]="q" name="searchfield"  (keyup)="watchChangesInSearchTerm($event)" placeholder="What are you searching for today?">

您正在使用ngModel双向绑定,因此您不需要使用模板中的数据手动更新q,而ngModel是什么是为了。你只需要听取关键事件,并做出反应。

在任何情况下,如果您确实需要将modelevent都传递给Subject.next(),您可以轻松地:

interface EventModel {
    model: string;
    event: KeyboardEvent;
}

(...)

txtQueryChanged: Subject<EventModel> = new Subject()

(...)

this.txtQueryChanged.next({
    model: model,
    event: event
});

接口的定义不是必需的,您可以将Subject定义为Subject<any>但是,使用TypeScript,我总是喜欢注释我的类型。一开始可能很麻烦,但从长远来看会有所回报。

除此之外,我建议你使用&#39;按键&#39;而不是&#39; keyup&#39;,但这取决于您和您的需求。

答案 1 :(得分:0)

在我的应用程序中,我在html

中进行了这样的搜索
<input type="text" name="search" #search class="form-control" (keyup)="doSearch(search.value)" required>

在de Component.ts

export class SearchViewComponent implements OnInit {
  @Output('searchQuery') sq: EventEmitter<string> = new EventEmitter();

  search: string;
  searchChanged: Subject<string> = new Subject<string>();

  constructor() {
    this.searchChanged
      .debounceTime(300)
      .distinctUntilChanged()
      .subscribe(searchValue => this.search = searchValue);
  }

  ngOnInit() {
  }

  doSearch(searchText) {
    this.sq.emit(searchText);
    this.searchChanged.next(searchText);
  }

}

我也向父组件@Output

发出声音