Angular獲取ngIf渲染的Dom元素示例
目錄
- Angular獲取普通Dom元素的方法
- 通過模板變量名獲取
- 將static改成false 獲取
- 自己實現的思路
- 通過cdkDragData 把拖拽的元素的value,id等值帶上
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渲染的資料請關注其它相關文章!