2017-07-26 8 views
2

は私がに結合てる深くネストされたオブジェクトグラフを持っていると言います。私は私のビューモデルにプロパティを公開することができますが、私はローカルコンテキストを作成するいくつかの方法を好むだろう。私の望む構文は、次のようなものになります。は角テンプレート内のローカルバインディングコンテキストを作成

<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はこれを必要としないようです。

これは可能ですか?

+0

はるかに単純な解決策のようですが、 "プランA"と一緒にあなたのビュー/モデルにプロパティを追加することです。それは結局その目的です。 :-) – DeborahK

+0

ええ、私のエイリアスがテンプレート内で明示的に存在すると、読みやすく/保守が容易なように感じます。ときどきこのパターンをネストすることができます。ネストされたプロパティのいくつかのネストされたプロパティを参照し、それに対して複数のviewmodelプロパティを設定しても、テンプレートでそのリレーションシップを見ることはできません。 – Mud

+0

はい、それを行うには 'ng-template'であなたのhtmlをラップする必要があります –

答えて

2

ディレクティブに類似する* ngIfと* ngForは* BindingContextをと呼ばれる構造を定義することが可能である:

<div *bindingContext = "let a_variable be an_expression"> 

角度は、この構文で舞台裏魔法の多くを行います。まず第一に、アステリックスは ng-template >を作成し、すぐに使用します。次に、マイクロシンタックスが評価され、bindingContextBeというディレクティブが呼び出されます。このディレクティブは、完全な説明がAngular documentationであり順番にa_variable

に割り当てられているテンプレートコンテキストに$implicitようan_expressionが利用できるようになります。

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:あなたのモジュールで演出を宣言することを忘れないでくださいを次のように

は私がBindingContextをを実装しました。

関連する問題