2017-06-20 158 views
0

我想教自己Angular 2(好吧,它實際上是Angular 4,但Google的編號方案有點時髦)。無論如何,到目前爲止,我已經能夠找出如何通過angular.io中的示例和在stackoverflow上回答的問題來使所有工作都成爲可能。但是,這個正在困擾着我。從兄弟組件傳遞數據到另一個角2

所以這裏是我的問題,我試圖建立一個搜索頁面,可以通過使用兩個不同的組件,搜索欄和結果頁面來篩選大量的JSON數據文件(如果有更好的方法來做到這一點,我都是耳朵)。我已經通過搜索欄收集數據,並通過路由器將數據傳遞到結果頁面,在那裏它將實際執行查詢和過濾,但是我無法獲取結果頁面以讀取數據來自查詢字符串。這裏是相關的文件。

搜索bar.component.ts

import { Component } from '@angular/core'; 
import { Router } from '@angular/router'; 

@Component({ 
    selector: 'search-bar', 
    templateUrl: './search-bar.component.html', 
    styleUrls: ['./search-bar.component.css'] 
}) 
export class SearchbarComponent { 

    langSelect: string = 'english'; // Default search language 

    searchTerm: string; 

    constructor(private router: Router) {} 

    searchForTerm() { 
     let data: string = this.searchTerm + '_' + this.langSelect 
     this.router.navigate(['/results', {searchData: data}]); 
    } 
} 

搜索results.component.ts

import { Component, OnInit } from '@angular/core'; 
import { ActivatedRoute, Params } from '@angular/router'; 

import { WordEntry } from '../../shared/models/word-entry'; 
import { DataRetrievalService } from '../../shared/services/data-retrieval.service'; 

@Component({ 
    templateUrl: './search-results.component.html', 
    styleUrls: ['./search-results.component.css'] 
}) 
export class SearchResultsComponent implements OnInit { 
    searchData: string; // Two parameters separated by '_'. search term is on the left and the language on the right 


    constructor(private dataSvc: DataRetrievalService, private route: ActivatedRoute) {} 

    ngOnInit() { 
     console.log('starting!'); 

     this.route.params.subscribe((params: Params) => { 
      this.searchData = params['searchData']; 
      console.log(this.searchData); 
     }); 
    } 
} 

-----------編輯 - -----------

search.module.ts

import { NgModule } from '@angular/core'; 
import { CommonModule } from '@angular/common'; 
import { RouterModule, Routes } from '@angular/router'; 
import { FormsModule } from '@angular/forms'; 

import { SearchbarComponent } from './searchBar/search-bar.component'; 
import { SearchComponent } from './searchComponent/search.component'; 
import { SearchResultsComponent } from './searchResults/search-results.component'; 
import { DataRetrievalService } from '../shared/services/data-retrieval.service'; 

const SearchRoutes: Routes = [ 
    { 
     path: 'search', 
     component: SearchComponent, 
     children: [ 
      { path: 'results', component: SearchResultsComponent } 
     ] 
    } 
]; 

@NgModule({ 
    imports: [ 
     CommonModule, 
     FormsModule, 
     RouterModule.forChild(SearchRoutes) 
    ], 
    exports: [ 
     RouterModule, 
     SearchbarComponent 
    ], 
    declarations: [ 
     SearchComponent, 
     SearchbarComponent, 
     SearchResultsComponent 
    ], 
    providers: [ 
     DataRetrievalService 
    ] 
}) 
export class SearchModule {} 

這兩個文件是搜索模塊中的兄弟組件,每個文件都位於其各自的文件夾中。

我的問題是,ngOnInit()看起來並不像它被調用,因爲沒有東西被打印到控制檯,而searchData類變量沒有任何內容。

關於我在做什麼錯的任何想法?預先感謝您的幫助!

+0

你能提供一個小提琴嗎?是以某種方式在你的模板中調用的「search-results.component.html」? –

+0

「搜索結果」故意缺少選擇器嗎?這個組件在什麼地方初始化?添加他們在問題中的模塊可能會有所幫助。我們需要更多信息來找出錯誤。 –

+0

您的SearchResultsComponent沒有選擇器,因此沒有任何東西可以導致它加載。 –

回答

1

我不是100%確定我做了什麼的因果關係,而是將SearchbarComponent和SearchResultsComponent提取到主應用程序模塊中,而不是在搜索模塊中,然後將其更改爲數據在視圖轉換之間被持久保存到服務中,我才能使用它。

我認爲服務[起初]發生的事情是SearchbarComponent正在與應用程序模塊服務實例交談(因爲它當前是導航欄的一部分),並且SearchResultsComponent正在與搜索模塊交談服務實例。

這裏有一些相關的文件:

app.module.ts

import { NgModule } from '@angular/core'; 
import { BrowserModule } from '@angular/platform-browser'; 
import { HttpModule, JsonpModule } from '@angular/http'; 
import { FormsModule } from '@angular/forms'; 

import { AppComponent } from './start/app.component'; 
import { HomeComponent } from './home/home.component'; 
import { ErrorComponent} from './error/error.component'; 
import { NavComponent } from './shared/navbar/navbar.component'; 
import { AppRoutingModule } from './shared/app.routing'; 
import { SearchbarComponent } from './searchBar/search-bar.component'; 
import { SearchResultsComponent } from './searchResults/search-results.component'; 

import { WordEntry } from './shared/models/word-entry'; 
import { LexiconComponent } from './lexicon/lexicon.component'; 
import { DataRetrievalService } from './shared/services/data-retrieval.service'; 
import { TruncatePipe } from './shared/pipes/trunc.pipe'; 

@NgModule({ 
    imports: [ 
     BrowserModule, 
     FormsModule, 
     AppRoutingModule, 
     HttpModule, 
     JsonpModule 
    ], 
    exports: [ 
     TruncatePipe 
    ], 
    declarations: [ 
     AppComponent, 
     NavComponent, 
     HomeComponent, 
     ErrorComponent, 
     LexiconComponent, 
     TruncatePipe, 
     SearchbarComponent, 
     SearchResultsComponent 
    ], 
    providers: [ 
     DataRetrievalService 
    ], 
    bootstrap: [ AppComponent ] 
}) 
export class AppModule {} 

search.service.ts

import { Injectable } from '@angular/core'; 
import { BehaviorSubject } from 'rxjs/Rx'; 
import { Observable } from 'rxjs/Observable'; 


@Injectable() 
export class SearchService { 

    private _searchData = new BehaviorSubject<string>(''); // Initialize with emtpy string 

    setSearchData(data: string) { 
     // Fire the update event with the new data 
     this._searchData.next(data); 
    } 

    getSearchData(): Observable<string> { 
     return this._searchData.asObservable(); 
    } 
} 

搜索bar.component .ts

import { Component } from '@angular/core'; 
import { Router } from '@angular/router'; 

import { DataRetrievalService } from '../shared/services/data-retrieval.service'; 

@Component({ 
    selector: 'search-bar', 
    templateUrl: './search-bar.component.html', 
    styleUrls: ['./search-bar.component.css'] 
}) 
export class SearchbarComponent { 

    langSelect: string = 'english'; // Default search language 

    searchTerm: string; 

    constructor(private router: Router, private searchSvc: SearchService) {} 

    searchForTerm() { 
     let data: string = this.searchTerm + '_' + this.langSelect 

     // Update the service 
     this.searchSvc.setSearchData(data); 

     // No need to change routes if you're already on that page, even if it's a no op. 
     if (this.router.url != '/search') { 
      this.router.navigate(['/search']); 
     } 
    } 
} 

search-results.component。TS

import { Component, OnInit } from '@angular/core'; 
import { ActivatedRoute, Params } from '@angular/router'; 

import { WordEntry } from '../shared/models/word-entry'; 
import { DataRetrievalService } from '../shared/services/data-retrieval.service'; 

@Component({ 
    templateUrl: './search-results.component.html', 
    styleUrls: ['./search-results.component.css'] 
}) 
export class SearchResultsComponent { 
    searchData: string; // Two parameters separated by '_'. search term is on the left and the language on the right 

    constructor(private dataSvc: DataRetrievalService, private searchSvc: SearchService) { 
     // This should trigger anytime the searchbar is submitted 
     this.searchSvc.getSearchData().subscribe(searchData => { 

      // Don't even bother searching for an empty string 
      if (searchData != '') { 
       let parts = searchData.split('_', 2); 

       // Clear the searchResults, otherwise it just appends to the list with each search 
       this.searchResults = []; 

       this.searchForWord(parts[0], parts[1]); 
      } 
     }); 
    } 
} 

搜索result.component.html

<nav-bar></nav-bar> 

{{searchData}} 

我希望這可以幫助別人的路線。

相關問題