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渲染的资料请关注代码网其它相关文章!
发表评论