angular6 render2 & viewContentRef实践
angular 渲染层


angular一个跨平台的框架不仅仅针对的浏览器这一个平台
ElementRef 与 TemplateRef
简单的理解:
ElemnetRef : 例如一个<span>元素的引用;
TemplateRef: 例如template模板的引用;
再angular中,官方的说法是: 不推荐使用ElementRef来改变元素的样式属性值或者操作DOM元素,原因是,angular是一个跨平台的框架,如果直接使用ElementRef对DOM直接进行操作,那么在其他平台情况下会出事。那么真的的正规操作DOM是使用什么呢? 官方推荐: 仅使用render2来改变DOM元素的样式,仅使用viewContentRef来改变DOM的结构,不推荐使用render2来改变DOM结构,为什么呢?
不推荐使用Render2来改变DOM结构的原因
首先了解一下angular中如何将组件转为视图

view 与 HTML 元素的关系

使用render2操作DOM结构,只是将DOM的标签移除,但是在视图中的标签view并没有被真的移除,这就是为什么改变DOM结构不推荐使用render2的原因
实战
1. 使用TemplateRef关联元素 结合render2改变元素的样式
首先了解一下render2几个常用API

box.component.html
<div>div 1</div>
<div #targetDiv>targerDiv</div>
box.component.ts
export class BoxComponent implements OnInit, AfterViewInit {
@ViewChild('targetDiv') targetDiv: ElementRef;
constructor(private _elementRef: ElementRef,
private _render: Renderer2) { }
ngOnInit() {
}
ngAfterViewInit(): void {
this._render.setStyle(this.targetDiv.nativeElement, 'background', 'pink');
console.log(this._elementRef.nativeElement);
console.log(this.targetDiv);
}
}
效果图

2. 使用ViewContentRef创建元素
总体思路:viewContentRef引用<ng-container>标签,<ng-container>是angular里的一种映射,在没有真的内容出现的时候,<ng-container>只是一个隐式的占位符,最后动态生成的元素会被填充到这个占位符中,由viewContentRef的实例使用自带的API来创建元素,元素应该是一开始就写好的,但是其DOM结果没有被渲染出来,在angular中<ng-template>中的内容会被忽略,我们需要做的是创建<ng-tempate>的引用,然后给到viewContentRef的实例<ng-tempate>中的元素自然会被显示出来。
首先了解一下ViewContentRef的常用API

ViewContentRefComponent.html
<!--<ng-template><span #span>i am span to removed</span></ng-template>-->
<ng-template><a>i am a to removed</a></ng-template>
<ng-container #vc></ng-container>
<button (click)="remove()">remove</button>
<button (click)="create()">create</button>
ViewContentRefComponent.ts
export class ViewContentRefComponent implements OnInit, AfterViewInit {
// @ViewChildren('span') spanElemnet;
// @ViewChildren('a') aElement;
@ViewChild(TemplateRef) template;
@ViewChild('vc', {read: ViewContainerRef}) vc;
constructor() { }
ngOnInit() {
// console.log(this.spanElemnet);
console.log(this.template);
console.log(this.vc);
}
ngAfterViewInit(): void {
this.vc.createEmbeddedView(this.template);
// console.log(this.spanElemnet.length);
}
remove = () => {
this.vc.remove();
}
create = () => {
this.vc.createEmbeddedView(this.template);
}
}
2. 使用viewContentRef创建组件
总体思路: 创建一个组件;然后再要创建组件的另外一个组建中引用ViewContainerRef,将工厂解析器解析之后的组件(被创建的组件)ViewContainerRef的创建组件函数中即可
alerComponent.html
<p>name: {{name}}</p>
<p>age: {{age}}</p>
alerComponent.ts
export class AlertComponent implements OnInit {
@Input() name = '';
@Input() age = 0;
constructor() { }
ngOnInit() {
}
}
createAlert.html
<ng-template #contatiner></ng-template>
<button (click)="create()">create alter component</button>
<button (click)="remove()">remove component</button>
createAlert.componts.ts
export class CreateAlertComponent implements OnInit {
@ViewChild('contatiner', {read: ViewContainerRef}) contatiner;
alertComponent: ComponentRef<any>;
constructor(private componentFactoryResolver: ComponentFactoryResolver) { }
ngOnInit() {
}
create = (): void => {
this.contatiner.clear();
this.alertComponent = this.contatiner.createComponent(this.componentFactoryResolver.resolveComponentFactory(AlertComponent));
this.alertComponent.instance.name = 'lili';
this.alertComponent.instance.age = 12;
}
remove = (): void => {
// 被创建的组件进行自我销毁
this.alertComponent.destroy();
}
}
最终效果,可以拉取代码跑一下。
angular6 render2 & viewContentRef实践的更多相关文章
- angular6 开发实践基础知识汇总
1 事件处理 1.1 鼠标移入事件触发 (mouseenter)=" " eg: (mouseenter)="isCollapsed= ...
- 【asp.net core mvc + angular6实战】 - 1. 环境搭建
为什么打算写这些文章? 没有为什么,只是为了学习Angular和更了解.Net Core等技术 需要用到的技术? 后端使用.Net Core 2.1 + EF Core 2.1 + Mysql 5.7 ...
- webp图片实践之路
最近,我们在项目中实践了webp图片,并且抽离出了工具模块,整合到了项目的基础模板中.传闻IOS10也将要支持webp,那么使用webp带来的性能提升将更加明显.估计在不久的将来,webp会成为标配. ...
- Hangfire项目实践分享
Hangfire项目实践分享 目录 Hangfire项目实践分享 目录 什么是Hangfire Hangfire基础 基于队列的任务处理(Fire-and-forget jobs) 延迟任务执行(De ...
- TDD在Unity3D游戏项目开发中的实践
0x00 前言 关于TDD测试驱动开发的文章已经有很多了,但是在游戏开发尤其是使用Unity3D开发游戏时,却听不到特别多关于TDD的声音.那么本文就来简单聊一聊TDD如何在U3D项目中使用以及如何使 ...
- Logstash实践: 分布式系统的日志监控
文/赵杰 2015.11.04 1. 前言 服务端日志你有多重视? 我们没有日志 有日志,但基本不去控制需要输出的内容 经常微调日志,只输出我们想看和有用的 经常监控日志,一方面帮助日志微调,一方面及 ...
- 【大型网站技术实践】初级篇:借助Nginx搭建反向代理服务器
一.反向代理:Web服务器的“经纪人” 1.1 反向代理初印象 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从 ...
- Windows平台分布式架构实践 - 负载均衡
概述 最近.NET的世界开始闹腾了,微软官方终于加入到了对.NET跨平台的支持,并且在不久的将来,我们在VS里面写的代码可能就可以通过Mono直接在Linux和Mac上运行.那么大家(开发者和企业)为 ...
- Mysql事务探索及其在Django中的实践(二)
继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...
随机推荐
- gridcontrol复选框功能实现(超具体)
博主这几天就准备离职了,以后不再做.Net开发.因此这应该是我写的最后一篇关于dev控件的博文.既然是最后一篇,那就写的具体一些.画个圆满的省略号...... 本文介绍gridcontrol怎样实现复 ...
- MongoDB的一些操作技巧
去年三月底入职上海的一家互联网公司,由于项目使用的是MongoDB数据库所以有机会接触了MongoDB.在项目的开发过程中使用系统原有的一些方法查询MongoDB感觉很费力,用起来也不爽,所以私下里就 ...
- php 静态成员(static)抽象类(abstract)和接口(interface)
首先看一下静态成员(static)和普通成员(public; protect; private)的区别: 静态成员是属于类的,普通成员是属于对象的: 例如: <?php header(" ...
- Sql Server 2016 创建内存数据库
官方教程:https://docs.microsoft.com/en-us/sql/relational-databases/in-memory-oltp/survey-of-initial-area ...
- java JDBM2 的几个简单实例
JDBM2 提供了 HashMap 和 TreeMap 的磁盘存储功能,简单易用,用于持久化数据.特别适合用于嵌入到其他应用程序中. 磁盘数据库 HelloWorld.java import java ...
- 使用php ffmpeg处理视频
工作中遇到video加载视频的问题,但是视频封面在手机上无法取到视频的第一帧,video标签无法在手机上取到第一帧,经过几天的研究于搜索终于找到比较好用的办法,就是php ffmped 插件,该插件的 ...
- java之EJB
EjB,只是一个服务端运行组件,公开接口供客户端以C/S方式调用而已. 最直白,最本质的解释,可参见: http://blog.csdn.net/jojo52013145/article/detail ...
- [usaco2009nov]奶牛的图片
Farmer John希望给他的N(1<=N<=100,000)只奶牛拍照片,这样他就可以向他的朋友炫耀他的奶牛.这N只奶牛被标号为1..N.在照相的那一天,奶牛们排成了一排.其中第i个位 ...
- HDU2049 不容易系列之(4)考新郎 —— 错排
题目链接:https://vjudge.net/problem/HDU-2049 不容易系列之(4)——考新郎 Time Limit: 2000/1000 MS (Java/Others) Me ...
- Codeforces Round #304 (Div. 2) C. Soldier and Cards —— 模拟题,队列
题目链接:http://codeforces.com/problemset/problem/546/C 题解: 用两个队列模拟过程就可以了. 特殊的地方是:1.如果等大,那么两张牌都丢弃 : 2.如果 ...