简体   繁体   English

Angular2-为什么将Subject实例放置在ngOninit内?

[英]Angular2 - why instance of subject is placed inside the ngOninit?

I am using the following code from angular.io website. 我正在使用angular.io网站上的以下代码。 for getting searched observables. 用于获取可观察的东西。

import {Observable} from 'rxjs/Observable';
import {Subject} from 'rxjs/Subject';

import 'rxjs/add/observable/of';

import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/switchMap';

@Component({
  selector: 'app-dropdown-suggestion',
  templateUrl: './dropdown-suggestion.component.html',
  styleUrls: ['./dropdown-suggestion.component.css']
})
export class DropdownSuggestionComponent implements OnInit {

    userSuggestions: Observable<User[]>;
  userSuggestionsLoad: Subject<string> = new Subject<string>();

  constructor(protected apiService: ApiService,) { }

  ngOnInit() {
    this.userSuggestions = this.userSuggestionsLoad
      .debounceTime(300)        // wait 300ms after each keystroke before considering the term
      .distinctUntilChanged()   // ignore if next search term is same as previous
      .switchMap(term => this.apiService.search(term))
      .catch(error => {
        console.log(error);
        return Observable.of<User[]>([]);
      });
  }

  searchUsers(term) {
    const url = this.url + term ;
    this.userSuggestionsLoad.next(url);
  }

I want to understand why this.userSuggestionsLoad is placed inside the ngOninit always and if i place this outside it doesn't work. 我想知道为什么this.userSuggestionsLoad放在里面ngOninit始终,如果我把这个之外这是行不通的。

I want to understand this as I want to make this functionality as base component and want to extend this component in my other component. 我想了解这一点,因为我想将此功能作为基本组件,并希望在其他组件中扩展该组件。 but in that case this.userSuggestionsLoad is not getting triggered may be because of ngOninit . 但在这种情况下this.userSuggestionsLoad是没有得到触发可能是因为ngOninit

We need to write this.userSuggestionsLoad implementation inside ngOnInit since it is lifecycle hook and call during component init. 我们需要在ngOnInit内编写this.userSuggestionsLoad实现,因为它是组件初始化期间的生命周期挂钩和调用。 Here we need to implement subject since it is observable and we usually registered observable once and it get called when anything changed in it. 在这里,我们需要实现subject,因为它是可观察的,并且我们通常注册一次observable,并且在其中发生任何更改时都会调用它。

Now if you need your implementation avaibale inside child component you do as below: 现在,如果您需要在子组件内部实现实现,请执行以下操作:

export class DropdownSuggestionComponent implements OnInit {

    userSuggestions: Observable<User[]>;
  userSuggestionsLoad: Subject<string> = new Subject<string>();

  constructor(protected apiService: ApiService,) { }

  ngOnInit() {
    this.userSuggestions = this.userSuggestionsLoad
      .debounceTime(300)        // wait 300ms after each keystroke before considering the term
      .distinctUntilChanged()   // ignore if next search term is same as previous
      .switchMap(term => this.apiService.search(term))
      .catch(error => {
        console.log(error);
        return Observable.of<User[]>([]);
      });
  }


Now extending with another component

export class ChildComponent extends DropdownSuggestionComponent implement OnInit {

ngOnInit(): void {
super.ngOnInit(); // This code will call your parent class onInit which you want to execute
}

}

The reason is that When the component loads up after the constructor the ngOnInit life cycle hook is called. 原因是当组件在constructor之后加载时,将调用ngOnInit生命周期挂钩。

The order of lyfecycle hooks lyfecycle挂钩的顺序

在此处输入图片说明

For more info on it Link 有关更多信息,请链接

If you want to place the load outside you have to place it inside a method that is manually triggered by the user from a template or any other component. 如果要将load放置在外部,则必须将其放置在用户从模板或任何其他组件手动触发的方法中。

[or in other lifecycle hook event] [或在其他生命周期挂钩事件中]

UDPATE UDPATE

if you want to manually trigger the function you need to create a method in the component like 如果要手动触发功能,则需要在组件中创建一个方法,例如

call(){
 // the body
}

and call this from a template or any other component, like 然后从模板或其他任何组件(例如

<button (click) = "call" > Call Method </button> 

or 要么

let comp = new <componentName> ();
comp.call();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM