当前位置: 移动技术网 > IT编程>脚本编程>AngularJs > 详解Angular 自定义结构指令

详解Angular 自定义结构指令

2017年12月12日  | 移动技术网IT编程  | 我要评论
1. <ng-template>元素 import { component, templateref, viewcontainerref, viewc

1. <ng-template>元素

import { component, templateref, viewcontainerref, viewchild,
 afterviewinit } from '@angular/core';
@component({
 selector: 'app-code404',
 template: `
 <!-- 这里使用一个模板变量,在组件中使用@viewchild装饰器获取模板元素-->
  <ng-template #tpl>
   big keriy !
  </ng-template>
 `,
})
export class code404component implements afterviewinit{

 // @viewchild 装饰器获取模板元素
 @viewchild('tpl')
 tplref: templateref<any>;
 constructor(private vcref: viewcontainerref) {}
 ngafterviewinit() {

  // 使用viewcontainerref对象的createembeddedview方法创建内嵌视图。
  this.vcref.createembeddedview(this.tplref);
 } }

这样其实我们在视图中就得到了一个什么...啊,就是一个'big keriy !'的字符串。

2. ngtemplateoutlet指令

a. ngtemplateoutlet

和routeroutlet是一个意思,将视图(<ng-template>标签中的内容)放到对应的ngtemplateoutlet下面。

import { component } from '@angular/core';
 @component({
  selector: 'app-code404',
  template: `
   <ng-template #stpl>
    hello, semlinker!
   </ng-template>
   <ng-template #atpl>
    big keriy !
   </ng-template>
   <div [ngtemplateoutlet]="atpl"></div>
   <div [ngtemplateoutlet]="stpl"></div>
`, })
 export class code404component { }

最终的视图应该是:

big keriy !
hello, semlinker!

b. ngoutletcontex

看名字就知道意思。

ngtemplateoutlet指令基于templateref对象,在使用ngtemplateoutlet指令时,可以通过ngtemplateoutletcontext属性来设置来设置embeddedviewref的上下文对象。可以使用let语法来声明绑定上下文对象属性名。

import { component, templateref, viewcontainerref, viewchild,
 afterviewinit } from '@angular/core';
@component({
 selector: 'app-code404',
 template: `
  <!-- 这里的messagey映射到下面context中message 再使用插值表达式的方式显示message的值 -->
  <ng-template #stpl let-message="message">
   <p>{{message}}</p>
  </ng-template>
  <!-- 这里的messagey映射到下面context中message , let-msg是一种与语法糖的方式变量名是msg-->
  <ng-template #atpl let-msg="message">
   <p>{{msg}}</p>
  </ng-template>
  <!-- 若不指定变量值那么将显示 $implicit 的值-->
  <ng-template #otpl let-msg>
   <p>{{msg}}</p>
  </ng-template>
  <div [ngtemplateoutlet]="atpl"
     // 这里ngoutletcontext绑定的是context对象
     [ngoutletcontext]="context">
  </div>
  <div [ngtemplateoutlet]="stpl"
     [ngoutletcontext]="context">
  </div>
  <div [ngtemplateoutlet]="otpl"
     [ngoutletcontext]="context">
  </div>
 `,
})
export class code404component implements afterviewinit{
 @viewchild('tpl')
 tplref: templateref<any>;
 constructor(private vcref: viewcontainerref) {}
 ngafterviewinit() {
  this.vcref.createembeddedview(this.tplref);
 }
 context = { message: 'hello ngoutletcontext!',
  $implicit: 'great, semlinker!' };
  // 这里的$implicit是固定写法
}

先看输出的视图:

hello ngoutletcontext!
hello ngoutletcontext!
hello, semlinker!

3. ngcomponentoutlet指令

听着名字就很爽,这不是插入视图的,是插入组件的!

该指令使用声明的方式,动态加载组件。

先写组件,里面有两个。。组件:

 @component({
  selector: 'alert-success',
  template: `
   <p>alert success</p>
  `,
 })
 export class alertsuccesscomponent { }
 @component({
  selector: 'alert-danger',
  template: `
   <p>alert danger</p>
  `,
 })
 export class alertdangercomponent { }
 @component({
  selector: 'my-app',
  template: `
   <h1>angular version 4</h1>
   <ng-container *ngcomponentoutlet="alert"></ng-container>
   <button (click)="changecomponent()">change component</button>
 `, })
 export class appcomponent {
   alert = alertsuccesscomponent;
  changecomponent() {
   this.alert = alertdangercomponent;
 } 
}

当然,还需要在模块中声明入口:

// app.module.ts
@ngmodule({
  // ...
  declarations: [
   appcomponent,
   signupcomponent,
   alertsuccesscomponent,
   alertdangercomponent
  ],
  entrycomponents: [    // 这里面写指令中呀用到的组件
   alertsuccesscomponent,
   alertdangercomponent
],
// ...
})

这样就可以使用ngcomponentoutlet指令来插入组件玩耍了:

<!-- 简单语法 -->
<ng-container *ngcomponentoutlet="componenttypeexpression"></ng-container>

<!-- 完整语法 -->
<ng-container *ngcomponentoutlet="componenttypeexpression;
   injector: injectorexpression;
   content: contentnodesexpression;">
</ng-container>

这是一个完整语法简单的例子:

// ...
@component({
 selector: 'ng-component-outlet-complete-example',
 template: `
  <ng-container *ngcomponentoutlet="completecomponent; 
                   injector: myinjector; 
                   content: mycontent"></ng-container>`
})
class ngtemplateoutletcompleteexample {
 // this field is necessary to expose completecomponent to the template.
 completecomponent = completecomponent;
 myinjector: injector;

 mycontent = [[document.createtextnode('ahoj')], [document.createtextnode('svet')]];

 constructor(injector: injector) {
  this.myinjector = reflectiveinjector.resolveandcreate([greeter], injector);
 }
}

4. 创建结构指令

也想不出来一个什么好例子,抄一个例子过来:

// uless.directive.ts

import { directive, input, templateref, viewcontainerref } from '@angular/core';
 @directive({
   selector: '[exeunless]'
 })
 export class unlessdirective {
   @input('exeunless')
   set condition(newcondition: boolean) { // set condition
     if (!newcondition) {
       this.viewcontainer.createembeddedview(this.templateref);
     } else {
       this.viewcontainer.clear();
     } 
   }
   constructor(private templateref: templateref<any>,
     private viewcontainer: viewcontainerref) {
   } 
 }


 import { component } from '@angular/core';
 @component({
  selector: 'app-root',
  template: `
   <h2 *exeunless="condition">hello, semlinker!</h2>
  `,
 })
 export class appcomponent {
  condition: boolean = false;
 }


 // app.component.ts

 import { component } from '@angular/core';
 @component({
  selector: 'app-root',
  template: `
   <h2 *exeunless="condition">hello, semlinker!</h2>
  `,
 })
 export class appcomponent {
  condition: boolean = false;
 }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网