首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Angular模板中创建本地绑定上下文

在Angular模板中创建本地绑定上下文
EN

Stack Overflow用户
提问于 2017-07-27 05:17:54
回答 1查看 1.4K关注 0票数 3

假设我有一个深度嵌套的对象图,我要绑定到:

代码语言:javascript
复制
<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>

我不想重复这个访问器链。我知道我可以在我的视图模型上公开一个属性,但我更喜欢用某种方式来创建一个本地上下文。我想要的语法是这样的:

代码语言:javascript
复制
<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不需要这样的标记。

这个是可能的吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-27 06:50:42

可以定义一个类似于*ngIf和*ngFor的结构指令,称为*bindingContext:

代码语言:javascript
复制
<div *bindingContext = "let  a_variable  be  an_expression">

Angular在幕后用这个语法做了很多神奇的事情。首先,asterics创建了一个可以立即使用的。然后计算微语法,并调用名为bindingContextBe的指令。此指令使an_expression在模板上下文中作为$implicit可用,而模板上下文又被分配给a_variable

Angular documentation中有完整的解释。

我按如下方式实现了BindingContext:

代码语言:javascript
复制
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;
}

使用示例:

代码语言:javascript
复制
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:别忘了在你的模块中声明指令。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45337603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档