详解Angular 自定义结构指令


Posted in Javascript onJune 21, 2017

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;
 }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery重新播放css动画所遇问题解决
Aug 21 Javascript
js给网页加上背景音乐及选择音效的方法
Mar 03 Javascript
通过JS判断联网类型和连接状态的实现代码
Apr 01 Javascript
javascript实现类似java中getClass()得到对象类名的方法
Jul 27 Javascript
JQuery的Pager分页器实现代码
May 03 Javascript
JS实现css hover操作的方法示例
Apr 07 Javascript
jQuery实现web页面樱花坠落的特效
Jun 01 jQuery
iview给radio按钮组件加点击事件的实例
Sep 30 Javascript
js时间戳与日期格式之间相互转换
Dec 11 Javascript
layui的面包屑或者表单不显示的解决方法
Sep 05 Javascript
vue获取form表单的值示例
Oct 29 Javascript
vue 授权获取微信openId操作
Nov 13 Javascript
详解Angular2 之 结构型指令
Jun 21 #Javascript
JavaScript用200行代码制作打飞机小游戏实例
Jun 21 #Javascript
Angular.JS中指令ng-if的注意事项小结
Jun 21 #Javascript
jquery.validate表单验证插件使用详解
Jun 21 #jQuery
JS实现简单拖拽效果
Jun 21 #Javascript
详解Vue路由开启keep-alive时的注意点
Jun 20 #Javascript
jquery基于layui实现二级联动下拉选择(省份城市选择)
Jun 20 #jQuery
You might like
火影忍者:三大瞳力之一的白眼,为什么没有写轮眼那么出色?
2020/03/02 日漫
require(),include(),require_once()和include_once()的异同
2007/01/02 PHP
php自定义函数之递归删除文件及目录
2010/08/08 PHP
php打造属于自己的MVC框架
2012/03/07 PHP
用PHP提取中英文词语以及数字的首字母的方法介绍
2013/04/23 PHP
php中substr()函数参数说明及用法实例
2014/11/15 PHP
wampserver改变默认网站目录的办法
2015/08/05 PHP
PHP使用phpunit进行单元测试示例
2019/09/23 PHP
javascript css在IE和Firefox中区别分析
2009/02/18 Javascript
深入理解Javascript闭包 新手版
2010/12/28 Javascript
基于jQuery实现的Ajax 验证用户名是否存在的实现代码
2011/04/06 Javascript
JavaScript/jQuery 表单美化插件小结
2012/02/14 Javascript
Jquery通过JSON字符串创建JSON对象
2014/08/24 Javascript
node.js中的fs.utimesSync方法使用说明
2014/12/15 Javascript
Jquery的基本对象转换和文档加载用法实例
2015/02/25 Javascript
基于JavaScript实现移动端TAB触屏切换效果
2015/10/20 Javascript
将List对象列表转换成JSON格式的类实现方法
2016/07/04 Javascript
js document.getElementsByClassName的使用介绍与自定义函数
2016/11/25 Javascript
JavaScript实现的商品抢购倒计时功能示例
2017/04/17 Javascript
vue组件初学_弹射小球(实例讲解)
2017/09/06 Javascript
JS实现二维数组横纵列转置的方法
2018/04/17 Javascript
JS去除字符串最后的逗号实例分析【四种方法】
2019/06/20 Javascript
解决vue+router路由跳转不起作用的一项原因
2020/07/19 Javascript
在Vue里如何把网页的数据导出到Excel的方法
2020/09/30 Javascript
微信小程序入门之绘制时钟
2020/10/22 Javascript
js前端传json后台接收‘‘被转为quot的问题解决
2020/11/12 Javascript
深入理解Python中的元类(metaclass)
2015/02/14 Python
python正向最大匹配分词和逆向最大匹配分词的实例
2018/11/14 Python
Python中类的创建和实例化操作示例
2019/02/27 Python
PyTorch实现更新部分网络,其他不更新
2019/12/31 Python
关于Python不换行输出和不换行输出end=““不显示的问题(亲测已解决)
2020/10/27 Python
美国著名首饰网站:BaubleBar
2016/08/29 全球购物
西班牙拥有最佳品牌的动物商店:Animalear.com
2018/01/05 全球购物
C/C++ 笔试、面试题目大汇总
2015/11/21 面试题
内业资料员岗位职责
2014/01/04 职场文书
班级旅游计划书
2014/05/03 职场文书