Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript Angular2:如何在渲染组件之前加载数据?_Typescript_Angular_Angular2 Services_Angular2 Http - Fatal编程技术网

Typescript Angular2:如何在渲染组件之前加载数据?

Typescript Angular2:如何在渲染组件之前加载数据?,typescript,angular,angular2-services,angular2-http,Typescript,Angular,Angular2 Services,Angular2 Http,我试图在呈现组件之前从API加载事件。目前我正在使用我的API服务,我从组件的ngOnInit函数调用该服务 我的EventRegister组件: import {Component, OnInit, ElementRef} from "angular2/core"; import {ApiService} from "../../services/api.service"; import {EventModel} from '../../models/EventModel'; import {

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

我的
EventRegister
组件:

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
    }
}
我的
EventRegister
模板


嗨,这句话始终可见,即使尚未加载'ev property'
“ev属性”一加载,我就可以看到了。目前,我从未出现过。
{{event.id}
我的API服务

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();
        }     
    }     
}
第二个解决方案。我喜欢给出的答案

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

ngOnInit() {
    this.fetchEvent().then(event => this.ev = event);
}
fetchEvent():承诺{
返回此.apiService.get.event(this.eventId);
}
恩戈尼尼特(){
this.fetchEvent().then(event=>this.ev=event);
}

更新

  • 如果使用路由器,则可以使用生命周期挂钩或解析器延迟导航,直到数据到达。

  • 要在根组件的初始呈现之前加载数据,可以使用
    APP\u初始值设定项

原创

this.fetchEvent()之后执行
console.log(this.ev)
,这并不意味着
fetchEvent()
调用已完成,这只意味着它已被调度。当执行
console.log(this.ev)
时,甚至没有调用服务器,当然也没有返回值

更改
fetchEvent()
以返回
Promise

fetchEvent(){
返回此.apiService.get.event(this.eventId)。然后(event=>{
this.ev=事件;
console.log(event);//有一个值
console.log(this.ev);//有一个值
});
}
更改
ngOnInit()
以等待
承诺完成

ngOnInit(){
this.fetchEvent()。然后(()=>
console.log(this.ev));//现在有值;
}
这实际上不会为您的用例买很多东西

我的建议是:将整个模板包装在
(模板内容)

ngOnInit()中

isDataAvailable:boolean=false;
恩戈尼尼特(){
this.fetchEvent()。然后(()=>
this.isDataAvailable=true);//现在有值;
}

您可以Angular2+中使用解析程序预取数据,解析程序在组件完全加载之前处理数据

在许多情况下,您希望仅在发生某些事情时加载组件,例如,仅当用户已登录时才导航到仪表板,在这种情况下,解析程序非常方便

请看我为您创建的简单图表,了解如何使用解析器将数据发送到组件

解析器应用于您的代码非常简单,我创建了代码片段,让您了解如何创建解析器:

import { Injectable } from '@angular/core';
import { Router, Resolve, RouterStateSnapshot, ActivatedRouteSnapshot } from '@angular/router';
import { MyData, MyService } from './my.service';

@Injectable()
export class MyResolver implements Resolve<MyData> {
  constructor(private ms: MyService, private router: Router) {}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<MyData> {
    let id = route.params['id'];

    return this.ms.getId(id).then(data => {
      if (data) {
        return data;
      } else {
        this.router.navigate(['/login']);
        return;
      }
    });
  }
}
您可以在组件中访问它,如下所示:

/////
 ngOnInit() {
    this.route.data
      .subscribe((data: { mydata: myData }) => {
        this.id = data.mydata.id;
      });
  }
/////
路由中(通常在app.routing.ts文件中)类似的内容:


我发现一个很好的解决方案是在UI上执行以下操作:

<div *ngIf="isDataLoaded">
 ...Your page...
</div

…你的页面。。。

事实上,你的第一条评论效果很好。我只删除了整个
fetchEvent
函数,将
apiService.get.event
函数放在
ngOnInit
中,它按照我的意图工作。谢谢我也会尽快接受你们的答案。出于某种原因,我在Angular 1.x上使用了这种方法。嗯,这应该被看作是一种黑客行为,而不是一个合适的解决方案。我们应该在角5上做得更好。你到底不喜欢什么?我认为这两种方法都很好。我认为这个解决方案只适用于Angular 1,而不是Angular>=2,因为Angular的单向数据流规则禁止在合成视图后对其进行更新。这两个钩子都在组件的视图合成后触发。div根本不进行渲染。我们不想阻止它渲染,我们想延迟它。它不起作用的原因是angular2中没有双向绑定@phil你能解释一下它是如何为你工作的吗?好的,我正在使用
ChangeDetectionStrategy.Push
,将其更改为
ChangeDetectionStrategy.Default
使其与模板双向绑定。6。有效。我想你错过了
Routes
数组下的路由配置条目(通常在app.routing.ts文件中):
{path:'yourpath/:id',component:YourComponent,resolve:{myData:myData}}
@Voicu,它不应该涵盖所有部分,但我同意,它使答案更全面,所以我添加了。。。感谢您纠正最后一部分,路由中的resolve参数需要指向解析器本身,而不是数据类型,即
resolve:{myData:MyResolver}
myData是在MyService中定义的模型对象吗?此解决方案适用于在页面加载之前获取数据,但不适用于检查记录的用户或用户角色。为此,您应该使用GuardAuth gaurds也可以这样做为什么您使用Http而不是HttpClient?如果使用HttpClient,就不必像自动转换json那样将响应转换为json。
/////
 ngOnInit() {
    this.route.data
      .subscribe((data: { mydata: myData }) => {
        this.id = data.mydata.id;
      });
  }
/////
////
{path: 'yourpath/:id', component: YourComponent, resolve: { myData: MyResolver}}
////
<div *ngIf="isDataLoaded">
 ...Your page...
</div