我试图在呈现组件之前从API加载事件。目前我正在使用我的API服务,我从组件的ngOnInit函数调用该服务。
我的Event寄存器
组件:
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
模板
<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>
我的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();
}
}
}
组件在ngOnInit
函数中的API调用完成获取数据之前呈现。所以我从来没有看到我的视图模板中的事件ID。所以看起来这是一个ASYNC问题。我期望在设置了ev
属性后,绑定ev
(Event寄存器
组件)来完成一些工作。可悲的是,当属性被设置时,它不显示用*ngIF="ev"
标记的div
。
问:我用的方法好吗?如果没有;在组件开始渲染之前加载数据的最佳方法是什么?
注:本angular2教程使用了Ngonit
方法。
编辑:
两种可能的解决方案。首先是放弃felchEvents
,只在ngOnInit
函数中使用API服务。
ngOnInit() {
this._apiService.get.event(this.eventId).then(event => this.ev = event);
}
第二个解决方案。我喜欢给出的答案。
fetchEvent(): Promise<EventModel> {
return this._apiService.get.event(this.eventId);
}
ngOnInit() {
this.fetchEvent().then(event => this.ev = event);
}
我发现一个很好的解决方案是在UI上执行以下操作:
<div *ngIf="isDataLoaded">
...Your page...
</div
只有当:isDataLoaded为true时,才会呈现页面。
您可以在Angular2中使用Resolvers预取数据,Resolvers在您的组件完全加载之前处理您的数据。
在许多情况下,您希望仅在发生某些事情时加载组件,例如,仅当用户已登录时才导航到仪表板,在这种情况下,解析程序非常方便。
请看我为您创建的简单图表,了解如何使用解析器将数据发送到组件。
将解析器应用于代码非常简单,我为您创建了代码段,以了解如何创建解析器:
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;
}
});
}
}
在模块中:
import { MyResolver } from './my-resolver.service';
@NgModule({
imports: [
RouterModule.forChild(myRoutes)
],
exports: [
RouterModule
],
providers: [
MyResolver
]
})
export class MyModule { }
您可以在组件中访问它,如下所示:
/////
ngOnInit() {
this.route.data
.subscribe((data: { mydata: myData }) => {
this.id = data.mydata.id;
});
}
/////
在路由中(通常在app.routing.ts文件中):
////
{path: 'yourpath/:id', component: YourComponent, resolve: { myData: MyResolver}}
////
更新
>
如果使用路由器,则可以使用生命周期挂钩或解析器延迟导航,直到数据到达。https://angular.io/guide/router#milestone-五路卫
要在根组件的初始呈现之前加载数据,可以使用初始化器APP\u
将从后端呈现的参数传递到angular2引导方法
原创
在this.fetchEvent()之后执行
,这并不意味着console.log(this.ev)
时fetchEvent()
调用已完成,这只意味着它已被调度。当执行console.log(this.ev)
时,甚至没有调用服务器,当然也没有返回值。
将返回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
});
}
更改ngOnInit()
以等待promise完成
ngOnInit() {
this.fetchEvent().then(() =>
console.log(this.ev)); // Now has value;
}
这实际上不会为您的用例买很多东西。
我的建议是:将整个模板包装在一个
中。
在
ngOnInit()中
isDataAvailable:boolean = false;
ngOnInit() {
this.fetchEvent().then(() =>
this.isDataAvailable = true); // Now has value;
}
问题内容: 我被困住了。我在单独的文件上有几个单独的组件。如果我在main.jsx中渲染它们,如下所示: 一切正常,但我想知道这是否是一个好习惯?也许可以做一些像只有一个ReactDom.render这样的事情: 我尝试了各种LandingPageBox变量,以某种方式包括了其他两个组件,但没有运气。它们有时在页面外渲染,依此类推。我认为应该看起来像这样: 但是此代码仅呈现PageTop和Page
我正在使用Vue路由器和基于文件的组件。我打电话给其中一条路线并获取一个参数(slug),该参数使用axios从API获取json。 我使用“组件内保护”来实现这一点,使用名为beforeRouteEnter的方法。我正在将axios的响应传递到下一个方法。 这是可行的,但是,Vue在设置数据之前呈现视图。这将生成
问题内容: 我正在努力寻找一种方法来做到这一点。在父组件中,模板描述了及其元素,但将渲染委托给了另一个组件,如下所示: 每个myResult组件都呈现其自己的标签,基本上是这样的: 我之所以没有将其直接放在父组件中(避免需要使用myResult组件)是因为myResult组件实际上比此处显示的要复杂,因此我想将其行为放在单独的组件和文件中。 产生的DOM看起来很糟。我相信这是因为它无效,因为它只能
问题内容: 我有一个react组件,需要 在渲染之前 预先知道其尺寸 。 当我在jquery中制作一个小部件时,我可以在构建组件时提前获取容器的宽度。 这些容器的尺寸以及页面上的其他许多容器都在CSS中定义。谁在React中定义组件的高度,宽度和位置?我已经习惯了CSS并能够访问它。但是在React中,似乎我只能在组件渲染后访问该信息。 问题答案: 如前所述,在将元素呈现为DOM之前,您无法获得任
问题内容: 你能告诉我如何在react js中渲染列表吗?我喜欢这样 问题答案: 您可以通过两种方式进行操作: 第一: 第二: 直接在返回中编写map函数
所以基本上我有一个导航栏,可以在路线之间切换。当页面加载时,默认情况下会转到/home,但实际上不会呈现所提供的应用程序组件。我必须单击将您带到/主页的按钮才能渲染此内容。 我使用Redux的反应路由器。 这是我的浏览器路由器: 有什么建议吗?