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

Angular获取普通Dom元素的方法: 通过模板变量名获取 js复制代码import { Component, ViewChild, AfterViewInit } from '@angular/core'; @Component({ selector: 'my-app', template: `

Welcome to Angular World

Hello {{ name }}

`, }) export class AppComponent { name: string = 'Semlinker'; @ViewChild('greet') greetDiv: ElementRef; ngAfterViewInit() { console.log(this.greetDiv.nativeElement); } } 但我发现用这种方法获取ngIf渲染的元素时得到的是undefined html复制代码
需要这样获取 将static改成false js复制代码@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 js复制代码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数组。 js复制代码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 || []; }); js复制代码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本身也可以互相拖拽的处理,所以也需要一层判断来特殊处理。 js复制代码drop(event: CdkDragDrop) { 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); } 这样子组件和父组件的内部元素互相拖拽,也就能实现了 作者:后青春期的诗 链接:https://juejin.cn/post/7211387043615096891 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
作者:后青春期的诗

%s 个评论

要回复文章请先登录注册