在Angular模板中创建本地绑定上下文 [英] Create local binding context in Angular template
问题描述
说我绑定了一个深度嵌套的对象图:
Say I have a deeply nested object graph I'm binding to:
<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>
我不想重复访问器链.我知道我可以在视图模型上公开一个属性,但是我更喜欢某种创建本地上下文的方法.我想要的语法将是这样的:
I don't want to repeat that chain of accessors. I know I could expose a property on my viewmodel, but I'd prefer to some way to create a local context. My desired syntax would be something like:
<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>
,但是以这种方式包含的内容仍然具有该组件的父组件的上下文.
I tried creating a component whose template contained only <ng-content></ng-content>
, but content transcluded this way still has the context of the component's parent component.
我知道我可以将内部内容包装在< template>
中,并在组件中使用模板出口,但这比我更喜欢标记,而且看来* ngFor
不需要这个.
I know I could wrap the inner content in a <template>
and use a template outlet in my component, but that's more markup than I'd prefer, and it seems that *ngFor
doesn't need this.
这可能吗?
推荐答案
可以定义类似于* ngIf和* ngFor的结构指令,称为* bindingContext:
It is possible to define a structure directive similar to *ngIf and *ngFor called *bindingContext:
<div *bindingContext = "let a_variable be an_expression">
Angular使用此语法在幕后做了很多魔术.首先,星号创建一个< ng-template>模板.立即使用.然后评估微语法,并调用一个名为bindingContextBe的指令.该指令使 an_expression
在模板上下文中可作为 $ implicit
使用,该模板上下文又被分配给 a_variable
Angular does a lot of magic behind the scenes with this syntax. First of all, the asterics creates an <ng-template> which is used right away. Then the micro syntax is evaluated and a directive called bindingContextBe is called. This directive makes an_expression
available as $implicit
in the template context, which in turn is assigned to a_variable
我实现了BindingContext,如下所示:
I implemented BindingContext as follows:
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:别忘了在模块中声明方向.
PS: Don't forget to declare the directing in your module.
这篇关于在Angular模板中创建本地绑定上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!