Angular2 - 为什么主题的实例放在ngOninit中?

时间:2017-08-31 15:19:54

标签: angular angular2-components angular2-observables

我正在使用angular.io网站上的以下代码。获得搜索的可观察量。

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

我想了解为什么this.userSuggestionsLoad始终放在ngOninit内,如果我把它置于外面则不起作用。

我想理解这一点,因为我想将此功能作为基本组件,并希望在我的其他组件中扩展此组件。但在这种情况下,this.userSuggestionsLoad未被触发可能是因为ngOninit

2 个答案:

答案 0 :(得分:2)

我们需要在ngOnInit中编写this.userSuggestionsLoad实现,因为它是生命周期钩子并在组件init期间调用。这里我们需要实现主题,因为它是可观察的,我们通常会注册一次observable,当它发生任何变化时会被调用。

现在,如果您需要在子组件内部实现avaibale,请执行以下操作:

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
}

}

答案 1 :(得分:0)

  

原因是当组件在constructor之后加载时   调用ngOnInit生命周期钩子。

lyfecycle钩子的顺序

enter image description here

有关它的更多信息Link

如果要将load放在外面,则必须将其放在用户从模板或任何其他组件手动触发的方法中。

  

[或其他生命周期钩子事件]

<强> UDPATE

如果要手动触发在组件中创建方法所需的功能,如

call(){
 // the body
}

并从模板或任何其他组件调用此方法,例如

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

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