zoukankan      html  css  js  c++  java
  • Angular使用总结 --- 通过指令动态添加组件

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

    创建组件

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

    <aside class="hover-tip-wrapper">
      <span>{{tipText}}</span>
    </aside>
    HTML
    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'app-hovertip',
      templateUrl: './hovertip.component.html',
      styleUrls: ['./hovertip.component.scss']
    })
    export class HovertipComponent implements OnInit {
    
      public tipText: string;
      constructor() { }
    
      ngOnInit() {
      }
    
    }
    ts
    .hover-tip-wrapper{
        width: max-content;
        position: absolute;
        height: 30px;
        line-height: 30px;
        bottom: calc(100% + 5px);
        right: calc( -10px - 100%);
        background-color: rgba(#000000,.8);
        padding: 0 5px;
        border-radius: 3px;
    
        &::after{
            content: '';
            position: absolute;
            height: 0;
            width: 0;
            border: 4px solid transparent;
            border-top-color: rgba(#000000,.8);
            left: 10px;
            top: 100%;
        }
    
        span {
            color: #ccc;
            font-size: 12px;
        }
    }
    scss

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

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

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

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

    创建指令

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

    import { Input , Directive , ViewContainerRef , ComponentRef, ComponentFactory, HostListener , ComponentFactoryResolver} from '@angular/core';
    import { HovertipComponent } from './hovertip.component';
    @Directive({
      selector: '[appHovertip]'
    })
    export class HovertipDirective {
    
      public hovertip: ComponentRef<HovertipComponent>;
      public factory: ComponentFactory<HovertipComponent>;
      constructor(
        private viewContainer: ViewContainerRef,
        private resolver: ComponentFactoryResolver
      ) {
    // 获取对应的组件工厂
    this.factory = this.resolver.resolveComponentFactory(HovertipComponent); } @Input('appHovertip') tipText: string;  
    // 绑定鼠标移入的事件 @HostListener(
    'mouseenter') onmouseenter() {
       // 清空所有的view
      
    this.viewContainer.clear();
    // 创建组件
    this.hovertip = this.viewContainer.createComponent(this.factory);
    // 向组件实例传递参数
    this.hovertip.instance.tipText = this.tipText; }  
     // 绑定鼠标移出时的事件 @HostListener(
    'mouseleave') onmouseleave() { if (this.hovertip) {
      // 组件销毁
    this.hovertip.destroy(); } } }

      

      通过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

  • 相关阅读:
    arcmap发布服务报错:“Faild to publish service”
    GIS优秀博客以及网址收藏,持续更新
    AE实现拖拽
    【ArcGIS for Server】制作并发布GP服务--缓冲分析为例
    ArcGIS API for JavaScript经典例子
    ArcGIS API for JavaScript
    Console ArcEngine 许可绑定
    FK JavaScript:ArcGIS JavaScript类库加载不成功而导致的程序异常
    FK JavaScript之:ArcGIS JavaScript添加Graphic,地图界面却不显示
    ASP.NET发布后,功能不响应
  • 原文地址:https://www.cnblogs.com/shapeY/p/9275042.html
Copyright © 2011-2022 走看看