2016-09-19 20 views
1

検索フォームと結果表示を同じページに持つAngular 2アプリケーションを構築しています。結果セクションを表示するためにルーティングを使用しました。したがって、親コンポーネントは複数のフィールドを持つ検索フォームであり、子コンポーネントはバックエンドから結果を得て表示しています。親から子へデータを複数回渡す方法

検索条件に複数のフィールドが含まれているため、検索条件を共有コンポーネントを介して子コンポーネントに通知しています。

親コンポーネント:

@Component({ 
     templateUrl : 'app/search-form.template.html' 
    }) 
    export class SearchFormComponent { 

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

     submitSearch(){ 
      this.searchService.setSearchCriteria(this.model); 
      this.router.navigate(['search-form/search-result']); 
     } 

チャイルドコンポーネント:

@Component({ 
     templateUrl: 'app/search-result/search-result.template.html' 
    }) 
    export class SearchResultComponent implements OnInit{ 
     private searchResult = [] ; 
     constructor(private searchService: SearchService) { } 

     ngOnInit() { 
       this.searchService.getSearchResult().subscribe(data => { 
       this.searchResult = data; 
      }); 

    } 

ここでは、サービスコードである:

@Injectable() 
    export class SearchService{ 
     constructor (private http: Http) {} 

    setSearchCriteria(searchCriteria : SearchCriteria){ 
     this.searchCriteria = searchCriteria; 
    } 

    getSearchResult() : Observable<any> { 
     let body = JSON.stringify(this.searchCriteria); 
     let headers = new Headers({'content-type' : 'application/json'}); 
     let options = new RequestOptions({headers : headers}); 
     return this.http.post(this.baseUrl , body, options) 
      .map((res: Response) => res.json().root || {}); 
    } 

親子は、ルーティングを使用してロードされます。ここにルーティングの詳細があります

const appRoutes : Routes = [ 
     { 
     path: '', 
     redirectTo: '/search-form', 
     pathMatch: 'full' 
    }, 
    { 
     path: 'search-form', component: SearchFormComponent, 
     children: [ 
      { path: ''}, 
      { path: 'search-result', component: SearchResultComponent } 
     ] 
     } 
     ]; 

main.htmlはこのようになります。ここでは検索フォーム(親)は、親のsubmitSearch()メソッドが親から提出フォームに呼び出された「検索フォーム」を


          
  
<nav class="navbar" > 
 
     <div class="container-fluid"> 
 
      <router-outlet></router-outlet> 
 
     </div> 
 
     </nav>

検索form.template.htmlスニペット


          
  

 

 
     <form #searchForm="ngForm" class="form-horizontal" (ngSubmit)="submitSearch()"> 
 
     <!-- form fields --> 
 
     <button type="submit" class="btn btn-sm btn-primary pull-right">Submit</button> 
 
    
 
     <div class="panel panel-primary"> 
 
      <!-- Search Result here --> 
 
      <router-outlet></router-outlet> 
 
     </div>

をレンダリングされます。子コンポーネントにナビゲートし、searchResultを表示します。これまでは正常に動作しています。

私が望むのは、ユーザーが画面上で検索条件を変更し、再度[送信]ボタンを押す必要があるということです。 submitSearch()メソッドが呼び出されますが、子コンポーネントの結果は更新されません。私は、子コンポーネントがngOnInitメソッドでサービスを呼び出しているため、ルートが原因だと思います。結果を表示した後、私は同じページにいるので、送信ボタンを再入力しても子コンポーネントが再度作成されることはなく、データはリフレッシュされません。

親コンポーネントからの送信時に、新しいsearchResultで子を再ロードするにはどうすればよいですか。

+0

を追加することができますナビゲーション – mehta

答えて

1

これがどのように配線されているかは不明です。 SearchResultComponentSearchFormComponentの子であるとしますが、実行した後に自分のコンポーネントがあるかのように移動します。setSearchCriteriaテンプレートを見ることができないので、何が起こっているのかを理解することは難しいです。

私が通常これを行う方法は、setSearchCriteria()の直後に親のgetSearchResult()を実行し、その結果を子に@Inputで渡すことです。 ActivatedRouteサービスのようなものを使用して親をナビゲートする場合は、子コードをngOnInitからngOnChangesに移動します。ここで、入力が変更されたときに更新されます。

+0

返事ありがとう、私は質問にいくつかの詳細を追加しました。子の@Inputフィールドを使って子コンポーネントにデータを渡すことも考えていました。しかし、私はデータバインディングがを使用して行われないため、親が子にその情報を渡す方法はわかりません。これが些細なことであれば、私の知らないことには申し訳ありません。 – mehta

+0

OK、コードを少し変更しました。ルータを使用する代わりに、結果に基づいて結果セクションを表示/非表示にします。検索条件を提出すると、サービスを呼び出して結果を取得し、@Inputを使用して子コンポーネントに渡します。その作業は今:)あなたの助けをありがとう。あなたの答えを受け入れました – mehta

1

SearchServiceの内部にはSubjectが必要です。それはcurrentResultのようなものです。サブジェクトは双方向の観察可能なものであり、プロデューサとコンシューマの両方です。だから、親の側ではプロデューサー、子は消費者を終わらせることができます。

おそらくonInitで検索条件を設定したくないかもしれませんが、親で何らかのアクションが発生した場合はおそらくです。その後、の子どものために聴くことができます。

多分「rxjs /件名からこの

インポート{件名}のようなもの。

@Injectable() 
class SearchService { 
    private currentSearch = new Subject<any>(); 

    searchAndSetCurrent(criteria) { 
    this.http.get(..).toPromise().then(result => { 
     currentSearch.next(result); 
    }); 
    } 

    getCurrentSearch(): Observable<any> { 
    // asObservable is not really necessary as you can subscribe 
    // to a subject. But to make sure people calling this method 
    // don't try to emit anything, we should just limit it 
    // to the capabilities of an Observable 
    return this.currentSearch.asObservable(); 
    } 
} 

今や、親はsearchAndSetCurrentを呼び出すことができ、子供はサブスクライブすることができます。検索が親によって呼び出されるたびに、結果が子に入ったときに取得されます。

あなたが親に結果と何かをしたい場合は、検索方法がよりおよそSubjectについては

searchAndSetCurrent(criteria)L Promise<any> { 
    return this.http.get(..).toPromise().then(result => { 
    currentSearch.next(result); 
    return this; 
    }); 
} 

約束を返すことができます、あなたがショーにいくつかの詳細をcheck this out

関連する問題