【问题标题】:Angular2 - Fetch array through service before routing and rendering the componentAngular2 - 在路由和渲染组件之前通过服务获取数组
【发布时间】:2017-03-07 15:32:09
【问题描述】:

我试图在我的路由呈现我的组件之前获取数据。在 app-component 我从后端得到一个数组。这个数组通过 ItemsServices 传递给 Statisticlist,或者,这就是我想要的样子。问题是 Statisticlist 组件似乎在数组传递之前呈现,因此当来自 itemsService 的 console.log 项目时,它在 statisticlist 中未定义,但在 app 组件中未定义。在服务中设置值后如何继续渲染组件?

我查找了解析器,但我只找到了数据在路由中传递的示例,大多数情况下它是一个名为 id 的变量。我想通过服务传递我的数组,但在获取组件后加载它。我无法理解在我的情况下应该如何使用它。

根据第一个建议进行编辑:因此,我已使用解析器尽可能地关注 this 文章。我没有收到任何错误,但没有任何显示。 itemsArray 在 statisticlist-component 中仍未定义。这就是我的代码现在的样子。

编辑 2:我现在意识到在 statisticlist-component 中,我正在尝试 this.route.snapshot.params['items'] 但 items 不是路由的参数,就像在文章示例中一样。但是我如何让它做我正在尝试的事情做什么,我不知道。

编辑 3:我开始意识到解析器需要一个 observable,这就是我现在正在尝试的。现在还是运气。获取 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 { }

我在 statisticlist-component 中的 ngOnInit 看起来与文章中的不同。他需要使用通过解析器获得的 id 来获取联系人,但我只需要使用通过解析器获得的数组。有什么建议吗?

【问题讨论】:

    标签: javascript html angular routes frontend


    【解决方案1】:

    你实际上是在正确的轨道上。您正在研究解析器。这些解析器不能只返回字符串或其他原始类型。这些也可以返回一个可观察的。 angular2 路由器将在渲染组件之前等待该 observable 解析。

    基本大纲如下:

    定义一个获取数据并实现解析接口的解析器

     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 上找到一篇深入的文章

    【讨论】:

    • 嘿!谢谢你给我的建议。我按照说明做了,我通读了这篇文章。但我仍然有同样的问题。我将使用新代码编辑我的问题。你介意再看看吗?
    • 你在做this.items.items = items。问题是你还没有初始化`this.items。当您尝试为其分配项目时,这将是未定义的。
    猜你喜欢
    • 2021-04-08
    • 2018-02-19
    • 2016-06-09
    • 2019-02-08
    • 2017-01-06
    • 2021-07-12
    • 1970-01-01
    • 2018-11-11
    相关资源
    最近更新 更多