详解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 相关文章推荐
如何简单地用YUI做JavaScript动画
Mar 10 Javascript
JS面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)
Aug 16 Javascript
JS简单计算器实例
Jan 20 Javascript
JavaScript将数组转换成CSV格式的方法
Mar 19 Javascript
jQuery Easyui 下拉树组件combotree
Dec 16 Javascript
原生Javascript插件开发实践
Jan 09 Javascript
关于jQuery库冲突的完美解决办法
May 20 jQuery
Mac系统下Webstorm快捷键整理大全
May 28 Javascript
JavaScript数据结构之双向链表和双向循环链表的实现
Nov 28 Javascript
p5.js 毕达哥拉斯树的实现代码
Mar 23 Javascript
vue.js中使用微信扫一扫解决invalid signature问题(完美解决)
Apr 11 Javascript
微信小程序反编译的实现
Dec 10 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和ACCESS写聊天室(七)
2006/10/09 PHP
PHP显示今天、今月、上月、今年的起点/终点时间戳的代码
2011/05/25 PHP
PHP 清空varnish 缓存的详解(包括指定站点下的)
2013/06/20 PHP
header导出Excel应用示例
2014/01/24 PHP
php模拟登陆的实现方法分析
2015/01/09 PHP
php操作redis数据库常见方法实例总结
2020/02/20 PHP
javascript编程起步(第五课)
2007/01/10 Javascript
JavaScript中的逻辑判断符&amp;&amp;、||与!介绍
2014/12/31 Javascript
jQuery鼠标经过方形图片切换成圆边效果代码分享
2015/08/20 Javascript
微信小程序 高德地图SDK详解及简单实例(源码下载)
2017/01/11 Javascript
layui选项卡效果实现代码
2017/05/19 Javascript
js使用xml数据载体实现城市省份二级联动效果
2017/11/08 Javascript
vue input 输入校验字母数字组合且长度小于30的实现代码
2018/05/16 Javascript
layui使用form表单实现post请求页面跳转的方法
2019/09/14 Javascript
node后端服务保活的实现
2019/11/10 Javascript
js实现查询商品案例
2020/07/22 Javascript
python操作MongoDB基础知识
2013/11/01 Python
Python中的包和模块实例
2014/11/22 Python
python实现扫描日志关键字的示例
2018/04/28 Python
Python实现的多项式拟合功能示例【基于matplotlib】
2018/05/15 Python
Django模型修改及数据迁移实现解析
2019/08/01 Python
基于python计算并显示日间、星期客流高峰
2020/05/07 Python
Python新手学习函数默认参数设置
2020/06/03 Python
Python 微信公众号文章爬取的示例代码
2020/11/30 Python
来自世界各地的优质葡萄酒:VineShop24
2018/07/09 全球购物
俄罗斯药房连锁店:ASNA
2020/06/20 全球购物
质检部部长职责
2013/12/16 职场文书
校园达人秀策划书
2014/01/12 职场文书
四年级科学教学反思
2014/02/10 职场文书
民主评议党员自我评议范文2014
2014/09/26 职场文书
停电调休通知
2015/04/16 职场文书
《狮子和鹿》教学反思
2016/02/16 职场文书
个人销售励志奋斗口号
2019/12/05 职场文书
Python 中的单分派泛函数你真的了解吗
2021/06/22 Python
台积电称即便经济低迷也没有降价的计划
2022/04/21 数码科技
JavaScript实现一键复制内容剪贴板
2022/07/23 Javascript