2017-02-04 4 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 return Наблюдаемый поток (все, вплоть до подписки).

Затем, в вашем компоненте, после его инициализации, вы хотите подписаться на этот наблюдаемый поток.Так что ваш NarrowItDownComponent реализовать OnInit:

class NarrowItDownComponent implements OnInit { 

Затем создайте подписку на метод сервиса, что теперь возвращает наблюдаемый поток внутри ngOnInit метода:

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

Спасибо за ваш ответ. Даже если я переведу часть подписки в узле NarrowItDownComponent. Я получаю такое же поведение. Подкомпонент ничего не отображает. Я нажал свой новый код на github. –

+0

Здравствуйте, в вашем app.html у вас есть одинарные кавычки вокруг элементов меню: Можете ли вы попробовать изменить его на двойные кавычки? – muzurBurcu

+0

Пробовал простые и двойные кавычки. Это ничего не меняет. –

Смежные вопросы