Angular使用总结

  之前自己写的公共组件,都是会先引入,需要调起的时候再通过service控制公共组件状态、值、回调函数什么的。但是有一些场景不适合这种方式,还是动态添加组件更加好。通过写过的一个小组件来总结下。

创建组件

  场景:鼠标移动到图标上时,展示解释性的说明文字。那就需要创建一个普通的tooltip组件。如下:

1<aside class="hover-tip-wrapper"> 2 <span>{{tipText}}</span> 3</aside>

HTML

1import { Component, OnInit } from '@angular/core'; 2 3@Component({ 4 selector: 'app-hovertip', 5 templateUrl: './hovertip.component.html', 6 styleUrls: ['./hovertip.component.scss'] 7}) 8export class HovertipComponent implements OnInit { 9 10 public tipText: string; 11 constructor() { } 12 13 ngOnInit() { 14 } 15 16}

ts

1.hover-tip-wrapper{ 2 width: max-content; 3 position: absolute; 4 height: 30px; 5 line-height: 30px; 6 bottom: calc(100% + 5px); 7 right: calc( -10px - 100%); 8 background-color: rgba(#000000,.8); 9 padding: 0 5px; 10 border-radius: 3px; 11 12 &::after{ 13 content: ''; 14 position: absolute; 15 height: 0; 16 width: 0; 17 border: 4px solid transparent; 18 border-top-color: rgba(#000000,.8); 19 left: 10px; 20 top: 100%; 21 } 22 23 span { 24 color: #ccc; 25 font-size: 12px; 26 } 27}

scss

  非常简单的一个组件,tipText来接收需要展示的文字。

  需要注意的是,声明组件的时候,除了需要添加到declarations中外,还记得要添加到entryComponents中。

1entryComponents: [HovertipComponent], 2declarations: [HovertipComponent, HovertipDirective]

  那entryComponents这个配置项是做什么的呢?看源码注释,大概意思就是:Angular会为此配置项中的组件创建一个ComponentFactory,并存放在ComponentFactoryResolver中。动态添加组件时,需要用到组件工厂,所以此配置是必不可少的。

创建指令

  通过指令为目标元素绑定事件,控制创建组件、传递tipText以及组件的销毁。

1import { Input , Directive , ViewContainerRef , ComponentRef, ComponentFactory, HostListener , ComponentFactoryResolver} from '@angular/core'; 2import { HovertipComponent } from './hovertip.component'; 3@Directive({ 4 selector: '[appHovertip]' 5}) 6export class HovertipDirective { 7 8 public hovertip: ComponentRef<HovertipComponent>; 9 public factory: ComponentFactory<HovertipComponent>; 10 constructor( 11 private viewContainer: ViewContainerRef, 12 private resolver: ComponentFactoryResolver 13 ) { // 获取对应的组件工厂 14 this.factory = this.resolver.resolveComponentFactory(HovertipComponent); 15 } 16 @Input('appHovertip') tipText: string; 17  // 绑定鼠标移入的事件 18 @HostListener('mouseenter') onmouseenter() {   // 清空所有的view    this.viewContainer.clear(); // 创建组件 19 this.hovertip = this.viewContainer.createComponent(this.factory); // 向组件实例传递参数 20 this.hovertip.instance.tipText = this.tipText; 21 } 22  // 绑定鼠标移出时的事件 23 @HostListener('mouseleave') onmouseleave() { 24 if (this.hovertip) {  // 组件销毁 25 this.hovertip.destroy(); 26 } 27 } 28}

  通过ViewContainerRef类来管理视图,这里用到了创建组件。这个 专栏 解释的挺清楚的。这里用到了以下两个API,清除和创建。

  createComponent方法接受ComponentFactoty类,创建后返回的ComponentRef类,可以获取到组件实例(instance),控制组件销毁。

  大致思路是这样的,先获取到了HovertipComponent组件对于的componentFactory,监听鼠标移入事件,在触发事件时,通过ViewContainerRef类来创建组件,存下返回的组件componentRef(获取实例,销毁组件时需要用到),向组件实例传递tipText。监听鼠标移出事件,在事件触发时,销毁组件。

使用

  在目标元素是绑定指令,同时传递tipText即可。

  可以正常的创建和销毁。

总结

  开始做的时候,主要是对这几个类比较懵,ViewContainerRef、ComponentRef、ComponentFactory、ComponentFactoryResolver等,看看源码,查查资料,总会梳理清楚的。

  参考资料:

   https://segmentfault.com/a/1190000008672478#articleHeader1

   https://segmentfault.com/a/1190000009175508

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java将前端的json数组字符串转换为列表

记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang