2016-07-24 50 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