Angular获取ngIf渲染的Dom元素示例

 更新时间:2023年05月12日 14:03:52   作者:后青春期的诗  
这篇文章主要为大家介绍了Angular获取ngIf渲染的Dom元素示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

Angular获取普通Dom元素的方法

通过模板变量名获取

import { Component, ViewChild, AfterViewInit } from '@angular/core';
@Component({
  selector: 'my-app',
  template: `
    <h1>Welcome to Angular World</h1>
    <p #greet>Hello {{ name }}</p>
  `,
})
export class AppComponent {
  name: string = 'Semlinker';
  @ViewChild('greet')
  greetDiv: ElementRef;
  ngAfterViewInit() {
    console.log(this.greetDiv.nativeElement);
  }
}

但我发现用这种方法获取ngIf渲染的元素时得到的是undefined

<div *ngIf="isButtnGrop" (click)="dropBtnClick($event)">
  <div cdkDropList #dropList [cdkDropListConnectedTo]="_connectableDropLists" (cdkDropListDropped)="drop($event)">
    <div *ngFor="let item of itemDatas" (click)="onItemClick($event,item)" cdkDrag
      (cdkDragStarted)="startDragging($event)" [cdkDragData]="{ item }">
    </div>
  </div>
</div>

将static改成false 获取

@ViewChild('dropList', { read: CdkDropList, static: false }) dropList: CdkDropList;
ngAfterViewInit(): void {
    if (this.dropList) {
      console.log(this.dropList)
    }
  }

通过这个也是实现了一个buttonGroup拖拽button到 列表的功能,列表的button也能拖拽到 buttonGroup
用的也是Angular自带的 cdk/drag-drop

import { CdkDragDrop, CdkDropList, moveItemInArray } from '@angular/cdk/drag-drop';

自己实现的思路

官网的文档和demo比较简单,没有讲到跨组件的实现,简单记录一下自己实现的思路。

将需要拖拽的元素加入cdkDropList,并且在A组件和B组件都初始化的时候获取到需要拖拽的dom元素,将他们各自注册到store中,带上特殊的componentId。

A、B组件加上cdkDropListConnectedTo 这决定着组件可以跨组件拖动到哪里,用_connectableDropLists变量。同样的,在页面初始化时,通过rxjs的流订阅特殊的componentId,去获取到当有拖拽list注册到store中时的变化,并且赋值给_connectableDropLists数组。

const parentId = this.storeService.getProperty(this.pageId, this.componentId, 'parentId');
this.dragDropService.getDragListsAsync(this.pageId, parentId.value)
      .pipe(takeUntil(this.destroy))
      .subscribe(dropLists => {
        this._connectableDropLists = dropLists || [];
      });
this.storeService.getPropertyAsync(this.pageId, this.componentId, 'children')
      .pipe(takeUntil(this.destroy)).subscribe(result => {
        if (!result || result.length === 0) {
          this._children = [];
          this._dragData = [];
          this.changeRef.markForCheck();
        } else {
          const dropbuttonArray = result.filter((item) => {
            const itemType = this.storeService.getProperty(this.pageId, item, 'componentType');
            if (itemType === AdmComponentType.DropdownButton) return item;
          });
          if (dropbuttonArray.length > 0) {
            this._connectableDropLists = [];
            dropbuttonArray.forEach(comId => {
              this.dragDropService.getDragListsAsync(this.pageId, comId)
                .pipe(takeUntil(this.destroy))
                .subscribe(dropLists => {
                  this._connectableDropLists.push(...dropLists);
                });
            });
          }
        }
      });

因为A组件是B组件的父级,所以需要通过当前组件id获取到父级id,再获取到拖拽元素

通过cdkDragData 把拖拽的元素的value,id等值带上

通过(cdkDropListDropped)="drop($event)",注册拖拽结束的回调事件

drop回调事件处理拖拽结束后的数据处理,这里涉及到项目低代码的一些组件数据处理,大致是删除oldParent children, 然后新的parent节点加上,再更改当前组件的parent节点。同时这里涉及到buttongroup下面的button本身也可以互相拖拽的处理,所以也需要一层判断来特殊处理。

drop(event: CdkDragDrop<any>) {
    if (event.previousContainer != event.container) {
      const { eventData } = event.item.data;
      const componentId = eventData[event.previousIndex];
      const oldParentId = this.storeService.getProperty(this.pageId, componentId, 'parentId', false)?.value;
      // delete oldParent children
      const oldParent = this.storeService.getProperties(this.pageId, oldParentId);
      const index = oldParent.children.indexOf(componentId);
      oldParent.children.splice(index, 1);
      // add newParent children
      const oldChildren = this.itemDatas.map(x => x.id.value);
      oldChildren.splice(event.currentIndex, 0, componentId);
      this.storeService.setProperty(this.pageId, componentId, 'parentId', { value: this.componentId }, [[this.pageId, componentId]]);
      this.storeService.setProperty(this.pageId, oldParentId, 'children', oldParent.children, [[this.pageId, oldParentId]]);
      this.storeService.setProperty(this.pageId, this.componentId, 'children', oldChildren);
      this.changeDetector.markForCheck();
      return;
    }
    moveItemInArray(this.itemDatas, event.previousIndex, event.currentIndex);
    const children = this.itemDatas.map(x => x.id.value);
    this.storeService.setProperty(this.pageId, this.componentId, 'children', children);
  }

这样子组件和父组件的内部元素互相拖拽,也就能实现了

以上就是Angular获取ngIf渲染的Dom元素示例的详细内容,更多关于Angular获取ngIf渲染的资料请关注脚本之家其它相关文章!

相关文章

  • AngularJS中filter的使用实例详解

    AngularJS中filter的使用实例详解

    这篇文章主要介绍了AngularJS中filter的使用实例详解的相关资料,这里提供实例帮助大家理解掌握,希望能帮助到大家,需要的朋友可以参考下
    2017-08-08
  • Angular 中 select指令用法详解

    Angular 中 select指令用法详解

    这篇文章主要介绍了Angular 中 select指令用法详解的相关资料,本文介绍的非常详细,具有参考借鉴价值,需要的朋友可以参考下
    2016-09-09
  • 解决Angular4项目部署到服务器上刷新404的问题

    解决Angular4项目部署到服务器上刷新404的问题

    今天小编就为大家分享一篇解决Angular4项目部署到服务器上刷新404的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-08-08
  • 对Angular.js Controller如何进行单元测试

    对Angular.js Controller如何进行单元测试

    这篇文章主要给大家介绍了如何对Angular Controller进行单页测试。如果你不太了解angular也没关系,本文也会提及关于Angular的一些知识。文中通过示例代码介绍的很详细,详细对大家的理解和学习很有帮助,下面来一起看看吧。
    2016-10-10
  • AngularJS封装指令方法详解

    AngularJS封装指令方法详解

    这篇文章主要介绍了AngularJS封装指令方法,结合实例形式详细分析了AngularJS的功能、jQuery类库协作及组件封装的具体操作技巧,需要的朋友可以参考下
    2016-12-12
  • AngularJS监听ng-repeat渲染完成的两种方法

    AngularJS监听ng-repeat渲染完成的两种方法

    这篇文章主要介绍了AngularJS监听ng-repeat渲染完成的两种方法,结合实例形式分析了AngularJS基于自定义指令及广播事件实现监听功能的相关操作技巧,需要的朋友可以参考下
    2018-01-01
  • angular.foreach 循环方法使用指南

    angular.foreach 循环方法使用指南

    本文主要介绍了angular.foreach 循环方法使用格式及参数,是篇非常基础的文章,与需要的小伙伴参考下
    2015-01-01
  • Angularjs之如何在跨域请求中传输Cookie的方法

    Angularjs之如何在跨域请求中传输Cookie的方法

    跨域传输Cookie是需要后台和前台同时做相关处理才能解决的,这篇文章主要介绍了Angularjs之如何在跨域请求中传输Cookie的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • AngularJS实时获取并显示密码的方法

    AngularJS实时获取并显示密码的方法

    这篇文章主要介绍了AngularJS实时获取并显示密码的方法,涉及AngularJS数据绑定及显示相关操作技巧,需要的朋友可以参考下
    2018-02-02
  • AngularJS 打开新的标签页实现代码

    AngularJS 打开新的标签页实现代码

    本文通过实例代码给大家介绍了angularJS 打开新的标签页方法,代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-09-09

最新评论