0

我们一直面临将事件从 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 传递到参数中。watchChangesInSearchTerm依次对模型进行去抖动并调用getDetails方法。此方法也被许多其他用例调用,因此需要触发它的事件。

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

4

2 回答 2

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

于 2018-03-15T12:09:14.803 回答
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);
}

然后,在您的模板中,只需执行此操作,因为此处不需要 searchTerm:

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

您正在使用ngModel双向绑定,因此您不需要q使用模板中的数据手动更新,这就是ngModel目的。你只需要监听关键事件,然后做出反应。

无论如何,如果您真的需要同时传递modeleventSubject.next()您可以轻松地:

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

(...)

txtQueryChanged: Subject<EventModel> = new Subject()

(...)

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

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

除此之外,我建议您使用“keypress”而不是“keyup”,但这取决于您和您的需求。

于 2018-03-15T11:59:32.893 回答