假设我有一个要绑定的深层嵌套对象图:
<div>{{model.rootProperty}}</div>
<div>
<div>{{model.some.deeply.nested.property.with.a.donut.name}}</div>
<div>{{model.some.deeply.nested.property.with.a.donut.calories}}</div>
<div>{{model.some.deeply.nested.property.with.a.donut.deliciousness}}</div>
</div>
我不想重复该访问器链。我知道我可以在视图模型上公开一个属性,但我更喜欢某种方式来创建本地上下文。我想要的语法是这样的:
<div>{{model.rootProperty}}</div>
<div [binding-context]="model.some.deeply.nested.property.with.a.donut">
<div>{{name}}</div>
<div>{{calories}}</div>
<div>{{deliciousness}}</div>
</div>
我该怎么办呢?
我尝试创建一个组件,其模板仅包含<ng-content></ng-content>
,但是以这种方式嵌入的内容仍然具有该组件的父组件的上下文。
我知道我可以将内部内容包装在<template>
并在我的组件中使用模板出口,但这比我想要的更多标记,而且似乎*ngFor
不需要这个。
这可能吗?
可以定义一个类似于 *ngIf 和 *ngFor 的结构指令,称为 *bindingContext:
<div *bindingContext = "let a_variable be an_expression">
Angular 通过这种语法在幕后发挥了很多作用。首先,星号创建一个立即使用的 。然后对微语法进行评估并调用一个名为 bindingContextBe 的指令。该指令使得an_expression
可用为$implicit
在模板上下文中,它又被分配给a_variable
里面有完整的解释角度文档 https://v2.angular.io/docs/ts/latest/guide/structural-directives.html#!#microsyntax.
我实现 BindingContext 如下:
import {Directive, EmbeddedViewRef, Input,
TemplateRef, ViewContainerRef} from '@angular/core';
@Directive({selector: '[bindingContextBe]'})
export class BindingContextDirective {
private context = new BindingContextDirectiveContext();
private viewRef: EmbeddedViewRef<BindingContextDirectiveContext>|null = null;
constructor(private viewContainer: ViewContainerRef,
private templateRef: TemplateRef<BindingContextDirectiveContext>) {
}
@Input()
set bindingContextBe(context: any) {
this.context.$implicit = context;
if (!this.viewRef) {
this.viewContainer.clear();
this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef,
this.context);
}
}
}
export class BindingContextDirectiveContext {
public $implicit: any = null;
}
使用示例:
Full:
<div>
<div>{{model.some.deeply.nested.property.with.a.donut.name}}</div>
<div>{{model.some.deeply.nested.property.with.a.donut.calories}}</div>
<div>{{model.some.deeply.nested.property.with.a.donut.deliciousness}}</div>
<input [(ngModel)]="model.some.deeply.nested.property.with.a.donut.name">
</div>
<hr>
Alias:
<div *bindingContext="let food be model.some.deeply.nested.property.with.a.donut">
<div>{{food.name}}</div>
<div>{{food.calories}}</div>
<div>{{food.deliciousness}}</div>
<input [(ngModel)]="food.name">
</div>
PS:不要忘记在模块中声明指令。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)