这篇文章主要为大家介绍了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渲染的资料请关注编程学习网其它相关文章!
本文标题为:Angular获取ngIf渲染的Dom元素示例
基础教程推荐
- 解决ajax的delete、put方法接收不到参数的问题方法 2023-02-23
- ExtJS 3.x DateField menuListeners 显示/隐藏 2022-09-15
- ECSHOP中实现ajax弹窗登录功能 2023-01-31
- Vue+WebSocket实现在线聊天 2023-10-08
- vue的 Mixins (混入) 2023-10-08
- 关于 css:WebKit (iPad) CSS3: 背景过渡闪烁 2022-09-21
- 第7天:CSS入门 2022-11-04
- 基于bootstrap的上传插件fileinput实现ajax异步上传功能(支持多文件上传预览拖拽) 2023-02-01
- 深入浅析Jsonp解决ajax跨域问题 2022-12-28
- 分页技术原理与实现之无刷新的Ajax分页技术(三) 2023-01-20