我需要将模板数据变量与自己的服务绑定。服务使用HTTP以JSON格式检索数据。我得到了正确的数据,但因为请求是异步的,所以返回Service始终是未定义的。
如何将异步数据出售到模板中?没有使用回调?
AppComponent:
import {Component} from 'angular2/core';
import {RouteConfig, Router, ROUTER_DIRECTIVES} from 'angular2/router';
import {SystemComponent} from "./system.component";
import {MenuProvider} from "./providers/menuprovider";
import {Menu} from "./entity/menu";
import {Http, Headers, HTTP_PROVIDERS} from 'angular2/http';
@Component({
selector: 'app',
templateUrl: '/templates/layout',
directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
{
path: '/',
redirectTo: ['/System'],
useAsDefault: true
},
{
path: '/-1/...',
name: 'System',
component: SystemComponent
}
])
export class AppComponent {
menusItems:Array<Menu>;
constructor(router: Router, menuProvider:MenuProvider){
this.menusItems = menuProvider.getMenuItems(1);
router.navigate(['/System']);
}
}
MenuProvider:
import {Menu} from "../entity/menu";
import {IndexedCollection} from "../collections/IndexedCollection";
import {Injectable} from 'angular2/core'
import {Http, Headers, HTTP_PROVIDERS} from 'angular2/http';
@Injectable()
export class MenuProvider{
_menuItems:Array<Menu>;
private _http:Http;
constructor(http:Http){
this._http = http;
}
getMenuItems(shopId:number){
this.loadMenuForShopId(shopId);
return this._menuItems;
}
private loadMenuForShopId(shopId:number){
var base = this;
this._http.get('/services/menu/list/' + shopId)
.subscribe(
function(res){
res = res.json();
for(index in res['menuItems']){
var menu = res['menuItems'][index];
base._menuItems.push(new Menu(menu['url'], menu['name']));
}
}
);
}
}
MenuEntity:
export class Menu{
private _url;
private _name;
constructor(url:string,name:string){
this._url = url;
this._name = name;
}
get url() {
return this._url;
}
get name() {
return this._name;
}
}
模板:
<ul>
<li *ngFor="#menu of menusItems">
<a>{{menu.getName()}}</a>
</li>
</ul>
答案 0 :(得分:2)
查看 Observable ;它是你最好的朋友(;
你可以做'冷'&#34;可观察的(只是描述它应该做什么):
getMenuItems(shopId:number){
return this._http
.get('/services/menu/list/' + shopId)
.map(res => res.json())
.map(res => {
let menu = res.menuItems;
return new Menu(menu.url, menu.name)
})
}
...让角度使用AsyncPipe订阅它:
<ul>
<li *ngFor="#menu of menusItems |async">
<a>{{menu.getName()}}</a>
</li>
</ul>
AsyncPipe适用于Observables,Promises和Events ......
transform(obj: Observable<any>| Promise<any>| EventEmitter<any>, args?: any[]) : any
答案 1 :(得分:1)
请不要使用同步HTTP请求。这可能会阻止您的浏览器运行任何代码,直到请求完成为止。
在我看来,最好的解决方案是保持请求异步但向用户显示消息,例如&#34;正在加载...&#34;当你检索数据时。
您可以使用ngIf
指令以及在请求完成后变为true的变量。