2017-02-04 20 views
0

首先,我是angular2的新手,很抱歉,如果這是一個微不足道的問題。我試圖把一些代碼放在一個子組件中。我嘗試了很多東西,但似乎我無法弄清楚這一點。Angular2子組件html在加載後未刷新?

我想從json使用http get和subscribe得到一些結果。我的理解是數據在視圖創建後加載。我能夠在我的視圖中看到數據,但每當我嘗試將代碼負責顯示組件中的數據時。它不工作。

我能夠通過將ngFor放在找到項目組件外並在子組件中顯示一個項目來顯示數據。但我真的很想理解爲什麼當我將數組傳送到子組件時,我無法顯示數據。

在我看來,角沒有檢測到我的子組件變化,因爲我的數組沒有定義,當頁面第一次加載。

所有代碼可在GitHub

我父組件的HTML代碼如下:

<div class="container"> 
 
    <h1>Narrow Down Your Chinese Menu Choice</h1> 
 
    <div class="form-group"> 
 
     <input type="text" placeholder="search term" class="form-control" [(ngModel)]="searchTerm"> 
 
    </div> 
 
    <div class="form-group narrow-button"> 
 
     <button class="btn btn-primary" (click)="narrowItDown()">Narrow It Down For Me!</button> 
 
    </div> 
 
<ol> 
 
    <li *ngFor="let item of menuItems; let i = index; "> 
 
     {{ item.short_name }} : {{ item.name }} : {{ item.description }} 
 
     <button (click)="remove(i)">Don't want this one!</button> 
 
    </li> 
 
</ol> 
 
<found-items [items]='menuItems'></found-items> 
 
</div>

組件發現項不顯示任何內容。但是應用程序組件是。

我父組件TS的代碼如下:

import {Component,Output,OnInit} from '@angular/core'; 
 
import {MenuSearchService,MenuItem} from '../../services/menu-search-service'; 
 
import {Observable} from 'rxjs/Rx'; 
 
import { FoundItemsComponent } from '../../components/founditems/founditems.component'; 
 

 
@Component({ 
 
    selector: 'narrow-application', 
 
    templateUrl: `app/components/application/app.html`, 
 
}) 
 
export class NarrowItDownComponent { 
 
    @Output() menuItems:MenuItem[]; 
 
    searchTerm:string=""; 
 
    constructor(private menuSearchService: MenuSearchService) { 
 
    } 
 
    public getMatchedMenuItems(searchTerm:string){ 
 
     return this.menuSearchService.getMatchedMenuItems(searchTerm); 
 
    } 
 

 
    public narrowItDown(){ 
 
     console.log("searchTerm:"+this.searchTerm) 
 
     this.menuItems=this.getMatchedMenuItems(this.searchTerm); 
 
    } 
 

 
    public remove(index:number){ 
 
     console.log("index: "+index) 
 
     this.menuItems.splice(index,1); 
 
    } 
 

 

 
    
 
}

我可以看到,在ngOnChanges方法的子我的數據是可用的。

import {Component,Input,Output,AfterViewInit, ViewChild,ChangeDetectionStrategy,EventEmitter,ViewEncapsulation } from '@angular/core'; 
 
import {MenuSearchService,MenuItem} from '../../services/menu-search-service'; 
 
import {Observable} from 'rxjs/Rx'; 
 
import { NarrowItDownComponent } from '../../components/application/app.component'; 
 

 
@Component({ 
 
    selector: 'found-items', 
 
    templateUrl: `app/components/founditems/founditems.html`, 
 
}) 
 
export class FoundItemsComponent { 
 
    @Input('items') private items:MenuItem[]; 
 
    @Input('position') private position:number; 
 

 
    constructor() { 
 
    } 
 

 
    remove() { 
 
     console.log('remove'+this.position); 
 
    } 
 

 
    ngOnChanges(...args: any[]) { 
 
     console.log('changing', args); 
 
     console.log(this.items); 
 
    } 
 

 
}

服務代碼返回的數據是:

getMatchedMenuItems(searchTerm: string): MenuItem[] { 
var elements: MenuItem[] = []; 
this.http.get(this.constantService.API_ENDPOINT + "/menu_items.json") 
    .flatMap((response) => response.json()['menu_items']) 
    .filter((menu_item) => menu_item.description.toLowerCase().indexOf(searchTerm) !== -1) 

    .subscribe(

    (menu_item) => { 
    console.log(menu_item); 
    elements.push(new MenuItem(
     menu_item.id, 
     menu_item.short_name, 
     menu_item.name, 
     menu_item.description, 
     menu_item.price_small, 
     menu_item.price_large, 
     menu_item.small_portion_name, 
     menu_item.large_portion_name)); 
    } 

    , 
    function (error) { console.log("Error happened" + error) }, 
    function() { console.log("the subscription is completed") } 
); 

console.log("el :" + elements); 
return elements; 

}

回答

0

我想我找到了你的問題,這將是在呈現子組件時數據不可用。

我想這應該做的伎倆:

<div *ngIf="menuItems"> 
    <found-items [items]='menuItems'></found-items> 
</div> 

而且從你的父母刪除:

@Output() menuItems:MenuItem[]; 

,如果你想將一些數據從孩子送回父母只需要輸出。

除此之外,如做建議muzurBucu:

ngOnInit() { 
    this.menuSearchService.getMatchedMenuItems(yourSearchTerm) 
     .subscribe(items => { 
      // Your logic here 
     }); 
} 

然後,我覺得你是好去! :)

+0

感謝您的回覆。是的,這是我的意見。但是我所有嘗試使用ngIf =「menuItem」都不起作用。我不得不使用ngIf =「searchTerm」繞過這個。我想要一個更清潔的解決方案。 –

0

getMatchedMenuItems做訂閱本身。您將返回可能會或可能不會被填充的元素列表,因爲可觀察泵是異步的。

你需要做的是有getMatchedMenuItems返回可觀察流(一切直到訂閱)。

然後,在您的組件中,一旦初始化了,就要訂閱此可觀察的流。因此,有你NarrowItDownComponent實施OnInit

class NarrowItDownComponent implements OnInit { 

然後創建的訂閱服務的方法,現在ngOnInit方法中返回一個可觀察的數據流:

ngOnInit() { 
    this.menuSearchService.getMatchedMenuItems(yourSearchTerm) 
          .subscribe(items => { 
           // Your logic here 
          }); 
} 
+0

感謝您的回覆。即使我移動NarrowItDownComponent中的訂閱部分。我得到了同樣的行爲。子組件不顯示任何內容。我在github上推送了我的新代碼。 –

+0

你好,在你的app.html中,你有menuItems的單引號:你可以嘗試將它改爲雙引號嗎? – muzurBurcu

+0

試過簡單和雙引號。它不會改變任何東西。 –