2017-08-31 64 views
1

我从angular.io网站使用以下代码。为了获得搜索observables。Angular2 - 为什么主题的实例被放置在ngOninit中?

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

+1

张贴链接到您在哪里找到代码的地方 –

+0

https://v2.angular.io/docs/ts /latest/tutorial/toh-pt6.html –

回答

2

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

现在,如果你需要的子组件内的实施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 
} 

} 
+0

嗨它为我工作谢谢你的回答 –

+0

不客气:) .. –

0

的原因是,当constructorngOnInit生命周期钩组件后,负荷高达叫。

lyfecycle钩

enter image description here

的顺序有关它的详细信息Link

如果你要放置load之外你必须把它认为是手动触发的方法中由用户从模板或任何其他组件。

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

UDPATE

如果要手动触发需要像

call(){ 
// the body 
} 
创建在组件的方法的功能

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

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

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

我知道生命周期的顺序。我想知道为什么userSuggestionsLoad被放置在ngoninit中,为什么不在其他函数中,以及如何手动触发该函数。你能给我样品吗?我可以有这个功能通用,以便我可以在所有其他组件重用 –

+0

@SunilKumar更新了答案 –

+0

嗨,在这种情况下,我调用searchUsers(term)函数来触发搜索项更改。这个案例在这里有点棘手。userSuggestionsLoad在ngOninit中将只在组件中调用一次,但如果我直接在组件中使用它,它仍然可以正常工作。在这种情况下,我试图在单独的组件中使用它,以便我可以扩展该组件并重用它。但在那之后就失败了。它会触发搜索字词更改但不会触发api调用。 –

相关问题