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

原文地址:https://www.cnblogs.com/shapeY/p/9275042.html

时间: 2024-10-10 21:54:20

Angular使用总结 --- 通过指令动态添加组件的相关文章

Android使用addView动态添加组件

在项目开发中,我们经常需要进行动态添加组件,其中可添加的部分有两项:布局和组件 其中,添加的布局主要有RelativeLayout型(相对布局)的和LinearLayout(线性布局) 添加的组件主要有文本显示框,编辑框,按钮等组件. 下面,就让我们来进行实现: 首先我们创建一个新的项目,删除MainActivity.class中没有的代码,仅留下protected void onCreate(Bundle savedInstanceState)函数 往布局文件中添加一个新的组件: 1. add

angular 鼠标移入事件(动态添加类名)

不会弄动态图上来,只好截图了= = 大致就是这个样子,鼠标移入微博或者微信的框框里,就切换到相应的样式类名.图片.文字 原理:主要是做判断,判断true||false,然后根据它的布尔值来动态改变元素样式 html代码如下 绿色标记字体  属于写好了脚本之后注入的依赖,现在可不看 1 <div id="switch" switch=""> //将写好的依赖注入进去 2 <button class="switch" ng-clas

Android笔记(六十一)动态添加组件

想要一个功能,点击按钮,可以在已有的布局上,新添加一组组件. 动态的创建组件,本质上还是创建组件,只不过是在程序中根据逻辑来创建.大致步骤是找到要创建控件的位置,然后将要创建的组件添加进去. 看代码: MainActivity.java package com.example.test; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Bu

vue2.0动态添加组件

方法一.<template> <input type="text" v-model='componentName'> <button @click='add'>click me to add a component</button> </template> <script> // 引入要添加的所有组件 import component1 from './components/component1.vue' impo

动态添加组件(XML)

1.利用LayoutInflater的inflate动态加载XMLmLinearLayout = (LinearLayout)findViewById(R.id.LinearLayout_ID);LayoutInflater layoutInflater = LayoutInflater.from(context);View view = layoutInflater.inflate(resource--需要加载的XML, null);XML:resource = R.layout.XML-Na

easyui 使用jquery动态添加组件样式问题

可以使用$.parser.parse();这个方法进行处理: 例如: $.parser.parse(); 表示对整个页面重新渲染,渲染完就可以看到easyui原来的样式了: var targetObj = $("<input name='mydate' class='easyui-datebox'>").appendTo("#id"); $.parser.parse(targetObj); 表示重新渲染某个特定的组件.

ScrollView动态添加组件

main.xml代码如下: <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" a

New UI-Java代码动态添加控件或xml布局

New UI-Java代码动态添加控件或xml布局  --转载请注明出处:coder-pig,欢迎转载,请勿用于商业用途! 小猪Android开发交流群已建立,欢迎大家加入,无论是新手,菜鸟,大神都可以,小猪一个人的 力量毕竟是有限的,写出来的东西肯定会有很多纰漏不足,欢迎大家指出,集思广益,让小猪的博文 更加的详尽,帮到更多的人,O(∩_∩)O谢谢! 小猪Android开发交流群:小猪Android开发交流群群号:421858269 新Android UI实例大全目录:http://blog.

unity3d动态操作组件

利用范型,动态操作组件(添加或删除) e.AddComponent<CubeTranslate> ();//动态添加组件 Destroy (e.GetComponent<CubeTranslate> ());//动态删除组件 其中e为动态生成的对象: public GameObject e;