详解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 相关文章推荐
JavaScript入门教程 Cookies
Jan 31 Javascript
JS target与currentTarget区别说明
Aug 28 Javascript
window.open的页面如何刷新(父页面)上层页面
Dec 28 Javascript
Eclipse配置Javascript开发环境图文教程
Jan 29 Javascript
jQuery Validate初步体验(二)
Dec 12 Javascript
JavaScript编写页面半透明遮罩效果的简单示例
May 09 Javascript
javascript 常用验证函数总结
Jun 28 Javascript
JavaScript调用模式与this关键字绑定的关系
Apr 21 Javascript
vue移动端实现下拉刷新
Apr 22 Javascript
用vue快速开发app的脚手架工具
Jun 11 Javascript
vue中 this.$set的用法详解
Sep 06 Javascript
TypeScript 引用资源文件后提示找不到的异常处理技巧
Jul 15 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
php实例分享之通过递归实现删除目录下的所有文件详解
2014/05/15 PHP
laravel学习教程之关联模型
2016/07/30 PHP
Javascript中eval函数的使用方法与示例
2007/04/09 Javascript
JavaScript 题型问答有答案参考
2010/02/17 Javascript
javascript Array数组对象的扩展函数代码
2010/05/22 Javascript
javascript parseInt() 函数的进制转换注意细节
2013/01/08 Javascript
javascript通过className来获取元素的简单示例代码
2014/01/10 Javascript
jquery JSON的解析方式示例介绍
2014/07/27 Javascript
javascript检测是否联网的实现代码
2014/09/28 Javascript
jQuery中Form相关知识汇总
2015/01/06 Javascript
JavaScript中Null与Undefined的区别解析
2015/06/30 Javascript
JS实现自定义简单网页软键盘效果代码
2015/11/05 Javascript
果断收藏9个Javascript代码高亮脚本
2016/01/06 Javascript
jQuery 获取跨域XML(RSS)数据的相关总结分析
2016/05/18 Javascript
JS实现HTML标签转义及反转义
2020/04/14 Javascript
详解nodejs微信公众号开发——1.接入微信公众号
2017/04/10 NodeJs
JavaScript队列的应用实例详解【经典数据结构】
2017/04/12 Javascript
JS实现快递单打印功能【推荐】
2018/06/21 Javascript
axios简单实现小程序延时loading指示
2018/07/30 Javascript
jQuery实现获取及设置CSS样式操作详解
2018/09/05 jQuery
Vue实现input宽度随文字长度自适应操作
2020/07/29 Javascript
基于JavaScript的数据结构队列动画实现示例解析
2020/08/06 Javascript
vue等两个接口都返回结果再执行下一步的实例
2020/09/08 Javascript
在vant 中使用cell组件 定义图标该图片和位置操作
2020/11/02 Javascript
微信小程序实现列表左右滑动
2020/11/19 Javascript
[00:43]2016完美“圣”典风云人物:单车宣传片
2016/12/02 DOTA
浅谈python数据类型及类型转换
2017/12/18 Python
Python第三方Window模块文件的几种安装方法
2018/11/22 Python
在django admin中添加自定义视图的例子
2019/07/26 Python
Python代码覆盖率统计工具coverage.py用法详解
2020/11/25 Python
CSS3实现曲线阴影和翘边阴影
2016/05/03 HTML / CSS
HTML5通用接口详解
2016/06/12 HTML / CSS
2014银行授权委托书样本
2014/10/04 职场文书
2014年幼儿园教师工作总结
2014/11/08 职场文书
财务年终工作总结大全
2019/06/20 职场文书
Python使用Kubernetes API访问集群
2021/05/30 Python