2016-07-24 49 views
10

使用Angularjs 1.x,您可以在編輯/只讀模式之間點擊按鈕輕鬆切換html模板。 ng-include指令是關鍵。在用戶角度動態切換html模板2

<table> 
    <thead> 
     <th>Name</th> 
     <th>Age</th> 
     <th></th> 
    </thead> 
    <tbody> 
     <tr ng-repeat="contact in model.contacts" ng-include="getTemplate(contact)"> 
     </tr> 
    </tbody> 
</table> 

的get是getTemplate函數執行此代碼:

$scope.getTemplate = function (contact) { 
    if (contact.id === $scope.model.selected.id) return 'edit'; 
    else return 'display'; 
}; 

這又導致這些模板之一,活躍在UI:

顯示

<script type="text/ng-template" id="display"> 
     <td>{{contact.name}}</td> 
     <td>{{contact.age}}</td> 
     <td> 
      <button ng-click="editContact(contact)">Edit</button> 
     </td> 
    </script> 

編輯

<script type="text/ng-template" id="edit"> 
    <td><input type="text" ng-model="model.selected.name" /></td> 
    <td><input type="text" ng-model="model.selected.age" /></td> 
    <td> 
     <button ng-click="saveContact($index)">Save</button> 
     <button ng-click="reset()">Cancel</button> 
    </td> 
</script> 

https://jsfiddle.net/benfosterdev/UWLFJ/

具有角2 RC 4存在無正包括。

我該如何對Angular 2 RC4做同樣的功能?

回答

18

我將利用ngTemplateOutlet指令來做到這一點。

由於2.0.0 rc.2(2016年6月15日)上下文的版本加入NgTemplateOutlet

,所以你可以嘗試使用此功能在描述我demo plunker(更新爲4.XX

template.html

<table> 
    <thead> 
     <th>Name</th> 
     <th>Age</th> 
     <th></th> 
    </thead> 
    <tbody> 
     <tr *ngFor="let contact of contacts; let i = index"> 
      <ng-template [ngTemplateOutlet]="getTemplate(contact)" 
      [ngOutletContext]="{ $implicit: contact, index: i }"></ng-template> 
     </tr> 
    </tbody> 
</table> 


<ng-template #displayTmpl let-contact> 
    <td>{{contact.name}}</td> 
    <td>{{contact.age}}</td> 
    <td> 
     <button (click)="editContact(contact)">Edit</button> 
    </td> 
</ng-template> 

<ng-template #editTmpl let-i="index"> 
    <td><input type="text" [(ngModel)]="selected.name" /></td> 
    <td><input type="text" [(ngModel)]="selected.age" /></td> 
    <td> 
     <button (click)="saveContact(i)">Save</button> 
     <button (click)="reset()">Cancel</button> 
    </td> 
</ng-template> 

組件。TS

import { Component, ViewChild, TemplateRef } from '@angular/core'; 

interface Contact { 
    id: number; 
    name: string; 
    age: number 
} 

@Component({ 
    .... 
}) 
export class App { 
    @ViewChild('displayTmpl') displayTmpl: TemplateRef<any>; 
    @ViewChild('editTmpl') editTmpl: TemplateRef<any>; 

    contacts: Array<Contact> = [{ 
      id: 1, 
      name: "Ben", 
      age: 28 
     }, { 
      id: 2, 
      name: "Sally", 
      age: 24 
     }, { 
      id: 3, 
      name: "John", 
      age: 32 
     }, { 
      id: 4, 
      name: "Jane", 
      age: 40 
     }]; 

    selected: Contact; 

    getTemplate(contact) { 
     return this.selected && this.selected.id == contact.id ? 
     this.editTmpl : this.displayTmpl; 
    } 

    editContact(contact) { 
     this.selected = Object.assign({}, contact); 
    } 

    saveContact (idx) { 
     console.log("Saving contact"); 
     this.contacts[idx] = this.selected; 
     this.reset(); 
    } 

    reset() { 
     this.selected = null; 
    } 
} 
+0

令人敬畏的演示!代碼非常類似於角1.X!你能告訴我是什麼聲明:@ViewChild('editTmpl')editTmpl:TemplateRef ,我打字打字幾個星期了,我從來沒有見過這種語法。 – Pascal

+0

這只是訪問模板裏面的組件類https://angular.io/docs/ts/latest/api/core/index/TemplateRef-class.html – yurzui

+0

好的謝謝。我更喜歡你的解決方案,遠遠超過dfsq在RC2之前的角度2和你的角度爲RC2 +的實現方法:-) – Pascal

2

你需要改變你對這件事的想法。它不僅僅是一個模板,它是應用程序組件樹的一個分支。從組件角度考慮它,以及它們在應用程序中的用途。對於你的情況,如果你有「編輯」和「顯示」視圖,那麼設計你的應用程序時使用編輯和顯示組件並用ngIf或ngSwitch切換它們是有意義的。然後,這些組件中的每一個都需要能夠將數據模型作爲屬性(Input)並按照需要呈現它自己。

所以它可能是這樣的:

<tbody> 
    <tr *ngFor="let contact of model.contacts"> 
    <contact-display *ngIf="getView(contact) === 'display'" [contact]="contact"></contact-display> 
    <contact-edit *ngIf="getView(contact) === 'edit'" [contact]="contact"></contact-edit> 
    </tr> 
</tbody> 

UDP。下面是該辦法的一個簡單的演示:

http://plnkr.co/edit/drzI1uL4kkKvsrm0rgOq?p=info

+0

便創建了具有選擇接觸顯示/非接觸式的編輯和指令[聯繫方式]一個組成部分? – Pascal

+0

不,你不需要指令。它只是一個與財產聯繫(或其他)的組件。我會更新答案。 – dfsq

+0

檢查我創建的演示程序,我將如何做到這一點。 – dfsq