在渲染视图/模板之前,等待Angular 2加载/解析模型
在Angular 1.x中,UI路由器是我的主要工具。通过返回“解析”值的承诺,路由器只需等待承诺完成,然后再呈现指令 或者,在Angular 1.x中,空对象不会使模板崩溃-因此,如果我不介意临时不完整的渲染,我可以在在渲染视图/模板之前,等待Angular 2加载/解析模型,angular,promise,observable,dependency-resolver,Angular,Promise,Observable,Dependency Resolver,在Angular 1.x中,UI路由器是我的主要工具。通过返回“解析”值的承诺,路由器只需等待承诺完成,然后再呈现指令 或者,在Angular 1.x中,空对象不会使模板崩溃-因此,如果我不介意临时不完整的渲染,我可以在承诺之后使用$digest进行渲染。然后()填充最初为空的模型对象 在这两种方法中,如果可能的话,我更愿意等待加载视图,如果无法加载资源,则取消路线导航。这让我省去了“取消导航”的工作。编辑:注意,这特别意味着该问题要求使用Angular 2 futures兼容或最佳实践方法,并
承诺之后使用$digest
进行渲染。然后()
填充最初为空的模型对象
在这两种方法中,如果可能的话,我更愿意等待加载视图,如果无法加载资源,则取消路线导航。这让我省去了“取消导航”的工作。编辑:注意,这特别意味着该问题要求使用Angular 2 futures兼容或最佳实践方法,并要求尽可能避免使用“Elvis运算符”!因此,我没有选择这个答案
但是,这两种方法都不适用于Angular 2.0。当然,有一个标准的解决方案计划或可用于此。有人知道这是什么吗
@Component() {
template: '{{cats.captchans.funniest}}'
}
export class CatsComponent {
public cats: CatsModel;
ngOnInit () {
this._http.get('/api/v1/cats').subscribe(response => cats = response.json());
}
}
以下问题可能反映了相同的问题:。请注意,问题中没有代码或已接受的答案。在您的
@组件中执行激活
,并返回您的承诺:
编辑:这显然不起作用,尽管当前文档对此主题可能有点难以解释。更多信息,请参见Brandon的第一条评论:
编辑:通常准确的Auth0网站上的相关信息不正确:
编辑:angular团队正为此计划一个@Resolve装饰器。尝试{{model?.person.name}
这应该等待模型不未定义
,然后进行渲染
Angular 2将此?。
语法称为。在文档中很难找到对它的引用,因此这里有一份副本,以防他们更改/移动它:
Elvis运算符(?)和null属性路径
角度“Elvis”运算符(?)是防止属性路径中出现空值和未定义值的流畅且方便的方法。在这里,如果currentHero为空,则可以防止视图渲染失败
当前英雄的名字是{{currentHero?.firstName}}
让我们详细说明这个问题和这个特殊的解决方案
当以下数据绑定标题属性为null时会发生什么情况
标题为{{title}
视图仍然渲染,但显示值为空;我们只看到“标题是”,后面什么也没有。这是合理的行为。至少应用程序没有崩溃
假设模板表达式包含一个属性路径,如下一个示例中所示,我们将显示一个空英雄的名字
空英雄的名字是{{nullHero.firstName}}
JavaScript抛出空引用错误,Angular也抛出空引用错误:
TypeError:无法读取[null]中null的属性“firstName”
更糟糕的是,整个视图消失了
如果我们相信英雄属性永远不能为空,那么我们可以声称这是合理的行为。如果它永远不能为null,但它仍然为null,那么我们就犯了一个编程错误,应该捕获并修复它。抛出异常是正确的做法
另一方面,属性路径中的空值有时也可以,特别是当我们知道数据最终会到达时
当我们等待数据时,视图应该毫无怨言地呈现,空属性路径应该像title属性一样显示为空
不幸的是,当currentHero为空时,我们的应用程序崩溃
我们可以用NgIf解决这个问题
空英雄的名字是{{nullHero.firstName}}
或者我们可以尝试用&&链接属性路径的部分,知道表达式在遇到第一个null时退出
空英雄的名字是{{nullHero&&nullHero.firstName}
这些方法有其优点,但可能会很麻烦,特别是当属性路径很长时。想象一下,在长属性路径(如a.b.c.d)中的某个地方防范null
角度“Elvis”操作符(?)是防止属性路径中出现空值的更流畅、更方便的方法。表达式在遇到第一个空值时退出。显示为空白,但应用程序继续运行,没有错误
空英雄的名字是{{nullHero?.firstName}}
它也适用于长属性路径:
a?.b?.c?.d
使用观察者设置局部值
…此外,不要忘记使用虚拟数据初始化值,以避免未初始化的
错误
export class ModelService {
constructor() {
this.mode = new Model();
this._http.get('/api/v1/cats')
.map(res => res.json())
.subscribe(
json => {
this.model = new Model(json);
},
error => console.log(error);
);
}
}
该模型是表示数据结构的数据模型
没有参数的模型应该创建一个新实例,其中所有值都已初始化(但为空)。这样,如果模板在接收数据之前呈现,则不会抛出错误
理想情况下,如果您希望持久化数据以避免不必要的http请求,您应该将其放入一个对象中,该对象有自己的观察者,您可以订阅。编辑:angular团队已经发布了@Resolve decorator。它仍然需要一些澄清,说明它是如何工作的,但在此之前,我将在这里接受其他人的相关回答,并提供指向其他来源的链接:
编辑:此答案仅适用于Angular 2 BETA。截至本次编辑,角2 RC的路由器未发布。相反,当使用Angular 2 RC时,将对路由器的引用替换为路由器已弃用
,以继续使用beta路由器
安格尔
@CanActivate((to) => {
return new Promise((resolve) => {
to.routeData.data.user = { name: 'John' }
class Backend {
fetchTeam(id: string) {
return 'someTeam';
}
}
@Injectable()
class TeamResolver implements Resolve<Team> {
constructor(private backend: Backend) {}
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<any>|Promise<any>|any {
return this.backend.fetchTeam(route.params.id);
}
}
@NgModule({
imports: [
RouterModule.forRoot([
{
path: 'team/:id',
component: TeamCmp,
resolve: {
team: TeamResolver
}
}
])
],
providers: [TeamResolver]
})
class AppModule {}
// the no-observable method
this.dataYouResolved= this.route.snapshot.paramMap.get('id');
// console.debug(this.licenseNumber);
// or the observable method
this.route.paramMap
.subscribe((params: ParamMap) => {
// console.log(params);
this.dataYouResolved= params.get('id');
return params.get('dataYouResolved');
// return null
});
console.debug(this.dataYouResolved);
<div *ngIf="vendorServicePricing && quantityPricing && service">
...Your page...
</div