Angular2 -在路由和渲染组件之前,通过service获取数组
Angular2 - Fetch array through service before routing and rendering the component
我试图在我的路由呈现我的组件之前获取数据。在app-component中,我从后端得到一个数组。这个数组通过ItemsServices传递给Statisticlist,或者,这就是我想要的。问题是,似乎在数组传递之前,statisclist组件呈现,所以当console.log项目来自itemsService时,它在statisclist中未定义,但在app组件中没有定义。在服务中设置了值后,我如何继续渲染组件?
我已经查找了解析器,但我只找到了数据在路由中传递的例子,大多数时候它是一个名为id的变量。我想通过一个服务传递我的数组,但在它被获取后加载组件。我不明白在我这种情况下该怎么用它。
在第一个建议之后编辑:因此,我通过使用解析器尽可能地遵循这篇文章。我没有得到错误,但是什么也没有显示。itemsArray在statisticlist-component中仍然没有定义。这就是我的代码现在的样子。
编辑2:我现在意识到,在statisticlist-component中,我正在尝试this.route.snapshot.params['items']
,但项目不是路由的参数,就像在文章示例中一样。但我不知道如何让它做我想做的事。
编辑3:我已经意识到解析器需要一个可观察对象,这就是我现在正在尝试的。现在还是运气。无法在ItemsService上设置属性"items"的undefined。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看起来与本文中的ngOnInit不同。他需要使用他通过解析器获得的id获取联系人,但我只需要使用我通过解析器获得的数组。有什么建议吗?
你的思路是对的。你在研究解析器。这些解析器不能只返回字符串或其他基本类型。这些也可以返回一个可观察对象。angular2路由器会在渲染组件之前等待这个可观察对象解析完毕。
基本轮廓如下:
定义一个解析器来获取数据并实现解析接口
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
}
}
您可以在thought tram上找到更深入的文章http://blog.thoughtram.io/angular/2016/10/10/resolving-route-data-in-angular-2.html
- 创建一个类似链接的按钮,并通过Javascript函数打开一个新的弹出窗口
- 无法在通过jQuery的ajax加载的页面中执行javascript
- 如何通过ajax刷新JSF填充的javascript变量
- 通过javascript重定向html传递php变量
- 通过Magento的网络服务检索运费
- 无法通过数组映射绑定
- 通过单击表单中的按钮,在代码生成中使用javascript生成字母数字代码
- 通过js在新选项卡中有条件地打开url
- 如何使用jquery处理php循环通过元素
- 通过Ajax将JavaScript函数传递给PHP文件
- jquery动画可以通过编程链接吗
- 通过在Dojo mobile ViewController.openExternalView中动态更改打开同一外部视图的
- 如何通过数组更新角度子范围
- 如何通过php页面将数据库值检索到jquery自动完成框中
- 通过php页面中的js强制下载txt
- 我想使用模态通过php文件发送邮件,并且我希望在提交关闭后关闭pop
- 将通过Ajax(和Web Service方法)获得的数组转换为javascript数组
- JAX-RS Web Service 通过浏览器工作,但不通过 XMLHTTPRequest
- Angular2 -在路由和渲染组件之前,通过service获取数组
- 从$http service获取的数据不能通过ng-click获取