次のコンポーネントがあるとしましょう:
@Component({
selector: 'todo-lib',
template: `
<li *ngFor="let todo of libService.todos">
<div class="view">
<label>{{todo.title}}</label>
<ng-container *ngTemplateOutlet="incomingTemplate;context:ctx"></ng-container>
</div>
</li>
<ng-template #incomingTemplate let-service="templateService">
<button (click)="service.removeTodo(todo)">delete</button>
</ng-template>
`,
styles: []
})
export class TodoLibComponent implements OnInit {
ctx = {
templateService: this.libService
};
TodoのリストはlibService内にあります。ロジックは関係ないので、ここでは公開しません。 「ng-template」は別のコンポーネントから挿入され、私のToDoリストに削除ボタンが追加されます。つまり、「ng-template」が提供されることを除いて、通常は削除オプションはありません。
ただし、このアプローチは次のエラーで失敗します。
message: "_v.context.todo is undefined"
「todo」はコンテキストオブジェクト 'ctx'の一部ではないため、アクセスできません。これを達成するために、私は次のようにする必要があります。
<ng-container *ngTemplateOutlet="incomingTemplate;context:{ todo: todo}">
これにより、todoオブジェクトにアクセスできますが、サービスにはアクセスできなくなります。
NgForで定義された「todo」プロパティと「ctx」プロパティで定義されたサービスに同時にアクセスできないようです。両方を達成するための解決策はありますか?
乾杯
また、Angularの公式のgithubリポジトリでも言及しました。開発者による正しいアンサーは次のとおりです。
@dawidgarus:次のことができます:
<ng-container *ngTemplateOutlet="incomingTemplate;context:{ todo: todo, templateService: libService }">
加えて:
@dawidgarusの提案は良いものであり、現在のスコープでのスコープのしくみに従っていますAngular-もう一度見たいとは思いません。私が提案するのは、<ng-template>
要素の代わりに<ng-container>
を使用すると、生成されるコードが少なくなり、DOMなどに不要なコメントノードが作成されなくなります。
<ng-template [ngTemplateOutlet]="incomingTemplate" [ngTemplateOutletContext]="{ todo: todo, templateService: libService }">
そのため、ng-containerの代わりにng-templateを使用しました。
乾杯
関数と変数を渡す方が簡単なようです。
<ng-template #incomingTemplate let-service="templateService">
<button (click)="service">delete</button>
</ng-template>
その後
<ng-container *ngTemplateOutlet="incomingTemplate; context:removeTodo(todo)"></ng-container>