2016-10-25 7 views
0

Я пытаюсь извлечь данные до того, как мой маршрут отобразит мой компонент. В app-компоненте я получаю массив из бэкэнд. Этот массив передается через ItemsServices в Statisticlist, или так я и хочу. Проблема состоит в том, что кажется, что компонент Statisticlist отображается перед массивом, поэтому, когда элементы console.log из itemsService, он не определен в статистическом списке, но не в компоненте приложения. Как перейти к визуализации компонента ПОСЛЕ того, как значение установлено в сервисе?Angular2 - Извлечь массив через службу до маршрутизации и рендеринга компонента

Я искал Resolver, но я нахожу только примеры, где данные передаются по маршруту, в большинстве случаев это переменная с именем id. Я хочу передать свой массив через службу, но загрузите компонент после его получения. Я не могу понять, как я должен использовать его в своей ситуации.

EDIT после первого предложения: Итак, я следовал за статьей this, насколько мог, используя Resolver. Я не получаю ошибок, но ничего не появляется. Элемент itemsArray по-прежнему не определен в statisticlist-компоненте. Вот как выглядит мой код сейчас.

EDIT 2: Я понимаю теперь, что в statistlist-компоненте я пытаюсь this.route.snapshot.params['items'], но элементы не являются параметром маршрута, как в примере статьи. Но как я делаю это, делаю то, что я пытаюсь делаю, что я не знаю.

РЕДАКТИРОВАТЬ 3: Я понял, что резольвер требует наблюдаемого, и это то, что я сейчас пытаюсь сделать. Еще сейчас удача. Получение TypeError: Невозможно установить свойство «элементы» неопределенных на ItemsService.setItems (items.service.ts: 11)

//items 
export class Items { 
    constructor(public items: any[]){} 
} 

//itemsService 
import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs/Observable'; 
import { Items } from './items'; 

@Injectable() 
export class ItemsService { 
    public items: Items; 

    setItems(items: any[]) { 
    console.log(items); 
    this.items.items = items; 
    } 

    getItems() { 
    return Observable.create(observer => { 
     setTimeout(() => { 
     observer.next(this.items) 
     observer.complete(); 
     }, 3000); 
    }); 
    } 
} 

//items-resolve 
import { Component } from '@angular/core'; 
import { Resolve } from '@angular/router'; 
import { Items } from './items'; 
import { ItemsService } from './items.service'; 
import { Injectable } from '@angular/core'; 

@Injectable() 
export class ItemsResolve implements Resolve<Items>{ 

    constructor(private itemsService: ItemsService) { } 

    resolve() { 
     return this.itemsService.getItems(); 
    } 
} 

     <!-- app-component.html --> 
        <div class="btn-group btn-group-justified" role="group" aria-label="..." id="button-grp"> 
         <div class="btn-group" role="group"> 
          <a [routerLink]="['brott', region]"><button (click)='onClickCrimes(region)' type="button" class="btn btn-default">Brott</button></a> 
         </div> 
         <div class="btn-group" role="group"> 
          <a [routerLink]="['statistik', region]"><button (click)='onClickStatistics(region)' type="button" class="btn btn-default">Statistik</button></a> 
         </div> 
        </div> 
        <router-outlet></router-outlet> 
       </div> 


     //app.routing.ts 
    import { RouterModule, Routes } from '@angular/router'; 
    import { FeedlistComponent } from './feedlist/feedlist.component'; 
    import { StatisticlistComponent } from './statisticlist/statisticlist.component'; 
    import { ItemsResolve} from './items-resolve'; 

    const APP_ROUTES: Routes = [ 
     { path: 'brott/:region', component: FeedlistComponent }, 
     { path: 'statistik/:region', component: StatisticlistComponent, resolve: { items: ItemsResolve} }, 
     { path: '', component: FeedlistComponent } 
    ]; 

    export const routing = RouterModule.forRoot(APP_ROUTES); 

    //statisticlist.component.ts 
import { Component, OnInit, Input } from '@angular/core'; 
import { ItemsService } from '../items.service'; 
import { ActivatedRoute } from '@angular/router'; 
import { Items } from '../items'; 

@Component({ 
    selector: 'app-statisticlist', 
    templateUrl: './statisticlist.component.html', 
    styleUrls: ['./statisticlist.component.css'] 
}) 
export class StatisticlistComponent implements OnInit { 
    itemsArray: any[]; 
    items: Items; 
    constructor(private itemsService: ItemsService, private route: ActivatedRoute) { } 

    ngOnInit() { 
    this.items = this.route.snapshot.params['items']; 
    this.itemsArray = this.items.items; 
    console.log(this.itemsArray); 
    } 
} 

     <!-- statisticlist.component.html --> 
<div class="margin-top"> 
    <div *ngIf="isDataAvailable"> 
     <ul class="list-group" *ngFor="let item of itemsArray"> 
      <!-- ngFor, lista alla län och deras brottsstatistik --> 
      <li class="list-group-item list-group-item-info"> 
       <p>{{item?.region}}</p> 
      </li> 
      <li class="list-group-item">Invånare: {{item?.population}}</li> 
      <li class="list-group-item">Brott per kapita (denna veckan): {{item?.crimePerCapita}}%</li> 
     </ul> 
    </div> 
</div> 

//app.module.ts (I excluded all of the imports to make the reading easier) 
    @NgModule({ 
     declarations: [ 
     AppComponent, 
     MapComponent, 
     FeedlistComponent, 
     FeedComponent, 
     StatisticlistComponent, 
     StatisticComponent, 
     HeaderComponent, 
     ], 
     imports: [ 
     BrowserModule, 
     FormsModule, 
     HttpModule, 
     routing, 
     ], 
     providers: [HttpService, ItemsService, ItemsResolve], 
     bootstrap: [AppComponent], 
    }) 
    export class AppModule { } 

Моего ngOnInit в statisticlist-компоненте выглядит иначе, чем его в статье. Ему нужно получить контакт, используя идентификатор, который он получает через распознаватель, но мне просто нужно использовать массив, который я получаю через преобразователь. Любые предложения?

ответ

1

Вы были на правильном пути. Вы смотрели в резольверов. Эти резольверы могут не только возвращать строку или другой примитивный тип. Они также могут возвращать наблюдаемые. Маршрутизатор с угловым углом будет ждать, пока это будет видно, до того, как будет отображаться компонент.

основам Контуры:

Определить распознаватель, который извлекает данные и реализует интерфейс Resolve

export class ItemsResolve implements Resolve<Contact> { 

    constructor(private itemsService: ItemsService) {} 

    resolve(route: ActivatedRouteSnapshot) { 
     // should return an observable 
    return this.itemsService.getWhatever(); 
    } 
} 

Обеспечить ваш распознаватель

@NgModule({ 
    ... 
    providers: [ 
    ..., 
    ItemsResolve 
    ] 
}) 

точку в этом распознаватель в вашем определении маршрутов

{ 
    path: 'items', 
    component: ItemsComponent, 
    resolve: { 
    items: ItemsResolve 
    } 
}  

Вы можете найти подробную статью о ThoughtRam http://blog.thoughtram.io/angular/2016/10/10/resolving-route-data-in-angular-2.html

+0

Эй! Благодарим вас за предложения. Я сделал это как указано, и я прочитал статью. Но у меня все еще такая же проблема. Я отредактирую свой вопрос с помощью нового кода. Не возражаете ли вы иметь другой взгляд? – emmep

+0

Ваши действия 'this.items.items = items'. Проблема в том, что u не инициализировал 'this.items. Это будет неопределенным, если вы попытаетесь присвоить ему элементы. – KwintenP

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

  • Нет связанных вопросов^_^