Angular2:如何在渲染组件之前加载数据? [英] Angular2: How to load data before rendering the component?

查看:31
本文介绍了Angular2:如何在渲染组件之前加载数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在呈现组件之前从我的 API 加载事件.目前我正在使用我从组件的 ngOnInit 函数调用的 API 服务.

我的EventRegister 组件:

import {Component, OnInit, ElementRef} from "angular2/core";从../../services/api.service"导入{ApiService};从'../../models/EventModel'导入{EventModel};从 'angular2/router' 导入 {Router, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, RouteConfig, RouteParams, RouterLink};从'angular2/common'导入{FORM_PROVIDERS, FORM_DIRECTIVES, Control};@成分({选择器:注册",templateUrl: "/events/register"//提供者数组添加到父组件中})导出类 EventRegister 实现 OnInit {事件 ID:字符串;ev:事件模型;构造函数(私有_apiService:ApiService,参数:RouteParams) {this.eventId = params.get('id');}fetchEvent(): 无效 {this._apiService.get.event(this.eventId).then(event => {this.ev = 事件;控制台日志(事件);//有一个值控制台日志(this.ev);//有一个值});}ngOnInit() {this.fetchEvent();控制台日志(this.ev);//没有价值}}

我的EventRegister模板

嗨这句话总是可见的,即使`ev property`尚未加载<div *ngIf="ev">一旦加载了ev 属性",我就应该可见.目前我从未出现过.<span>{{event.id }}</span>

我的 API 服务

import "rxjs/Rx"从angular2/http"导入{Http};从angular2/core"导入{Injectable};从'../models/EventModel'导入{EventModel};@Injectable()导出类 ApiService {构造函数(私有http:Http){}得到 = {事件: (eventId: string): Promise=>{return this.http.get("api/events/" + eventId).map(response => {返回 response.json();//有一个值}).承诺();}}}

组件在 ngOnInit 函数中的 API 调用完成获取数据之前被渲染.所以我永远不会在我的视图模板中看到事件 ID.所以看起来这是一个 ASYNC 问题.我希望 ev(EventRegister 组件)的绑定在 ev 属性设置后做一些工作.遗憾的是,当属性被设置时,它没有显示用 *ngIf="ev" 标记的 div.

问题:我使用了一个好的方法吗?如果不;在组件开始呈现之前加载数据的最佳方式是什么?

注意: ngOnInit 方法用于此 angular2 教程.

两种可能的解决方案.首先是放弃 fetchEvent 并只使用 ngOnInit 函数中的 API 服务.

ngOnInit() {this._apiService.get.event(this.eventId).then(event => this.ev = event);}

第二种解决方案.就像给出的答案一样.

fetchEvent(): Promise{返回 this._apiService.get.event(this.eventId);}ngOnInit() {this.fetchEvent().then(event => this.ev = event);}

解决方案

更新

原创

console.log(this.ev)this.fetchEvent(); 之后执行时,这并不意味着 fetchEvent()code> call is done,这只意味着它被安排了.当 console.log(this.ev) 被执行时,甚至没有调用服务器,当然还没有返回值.

更改 fetchEvent() 以返回一个 Promise

 fetchEvent(){返回 this._apiService.get.event(this.eventId).then(event => {this.ev = 事件;控制台日志(事件);//有一个值控制台日志(this.ev);//有一个值});}

更改 ngOnInit() 等待 Promise 完成

 ngOnInit() {this.fetchEvent().then(() =>console.log(this.ev));//现在有值了;}

对于您的用例,这实际上不会给您带来太多好处.

我的建议:将整个模板包装在 <div *ngIf="isDataAvailable>>(模板内容)

和在 ngOnInit()

 isDataAvailable:boolean = false;ngOnInit() {this.fetchEvent().then(() =>this.isDataAvailable = true);//现在有值了;}

I am trying to load an event from my API before the component gets rendered. Currently I am using my API service which I call from the ngOnInit function of the component.

My EventRegister component:

import {Component, OnInit, ElementRef} from "angular2/core";
import {ApiService} from "../../services/api.service";
import {EventModel} from '../../models/EventModel';
import {Router, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, RouteConfig, RouteParams, RouterLink} from 'angular2/router';
import {FORM_PROVIDERS, FORM_DIRECTIVES, Control} from 'angular2/common';

@Component({
    selector: "register",
    templateUrl: "/events/register"
    // provider array is added in parent component
})

export class EventRegister implements OnInit {
    eventId: string;
    ev: EventModel;

    constructor(private _apiService: ApiService, 
                        params: RouteParams) {
        this.eventId = params.get('id');
    }

    fetchEvent(): void {
        this._apiService.get.event(this.eventId).then(event => {
            this.ev = event;
            console.log(event); // Has a value
            console.log(this.ev); // Has a value
        });
    }

    ngOnInit() {
        this.fetchEvent();
        console.log(this.ev); // Has NO value
    }
}

My EventRegister template

<register>
    Hi this sentence is always visible, even if `ev property` is not loaded yet    
    <div *ngIf="ev">
        I should be visible as soon the `ev property` is loaded. Currently I am never shown.
        <span>{{event.id }}</span>
    </div>
</register>

My API service

import "rxjs/Rx"
import {Http} from "angular2/http";
import {Injectable} from "angular2/core";
import {EventModel} from '../models/EventModel';

@Injectable()
export class ApiService {
    constructor(private http: Http) { }
    get = {
        event: (eventId: string): Promise<EventModel> => {
            return this.http.get("api/events/" + eventId).map(response => {
                return response.json(); // Has a value
            }).toPromise();
        }     
    }     
}

The component gets rendered before the API call in the ngOnInit function is done fetching the data. So I never get to see the event id in my view template. So it looks like this is a ASYNC problem. I expected the binding of the ev (EventRegister component) to do some work after the ev property was set. Sadly it does not show the div marked with *ngIf="ev" when the property gets set.

Question: Am I using a good approach? If not; What is the best way to load data before the component is starting to render?

NOTE: The ngOnInit approach is used in this angular2 tutorial.

EDIT:

Two possible solutions. First was to ditch the fetchEvent and just use the API service in the ngOnInit function.

ngOnInit() {
    this._apiService.get.event(this.eventId).then(event => this.ev = event);
}

Second solution. Like the answer given.

fetchEvent(): Promise<EventModel> {
    return this._apiService.get.event(this.eventId);
}

ngOnInit() {
    this.fetchEvent().then(event => this.ev = event);
}

解决方案

update

original

When console.log(this.ev) is executed after this.fetchEvent();, this doesn't mean the fetchEvent() call is done, this only means that it is scheduled. When console.log(this.ev) is executed, the call to the server is not even made and of course has not yet returned a value.

Change fetchEvent() to return a Promise

     fetchEvent(){
        return  this._apiService.get.event(this.eventId).then(event => {
            this.ev = event;
            console.log(event); // Has a value
            console.log(this.ev); // Has a value
        });
     }

change ngOnInit() to wait for the Promise to complete

    ngOnInit() {
        this.fetchEvent().then(() =>
        console.log(this.ev)); // Now has value;
    }

This actually won't buy you much for your use case.

My suggestion: Wrap your entire template in an <div *ngIf="isDataAvailable"> (template content) </div>

and in ngOnInit()

    isDataAvailable:boolean = false;

    ngOnInit() {
        this.fetchEvent().then(() =>
        this.isDataAvailable = true); // Now has value;
    }

这篇关于Angular2:如何在渲染组件之前加载数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆