从服务获取数据到模板

时间:2016-01-16 17:24:46

标签: angularjs angular

我需要将模板数据变量与自己的服务绑定。服务使用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>

2 个答案:

答案 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的变量。