angular4中modal的使用经验分享
本文是对实际项目中出现的一些问题进行的经验总结 很多业务场景中都会出现弹出modal框,填写详细信息或报错信息之类的业务需求,本文将对angular4中的modal如何进行数据交互,以及弹出及消失的控制进行一些心得分享 1.简单的父子关系由于modal总是由某个特定页面,经特殊操作后触发,所modal的component与触发它的component是具有父子关系的。而父子关系的数据传递相对比较简单,常用的有Input/Output传递数据,或通过service进行数据的中转,对于最简单的父-子组件数据传递,普通的Input/Output已经能满足要求 ModalComponent.ts export class ModalComponent implements OnInit{ // 用于接收需要在modal框中显示的信息或者其他什么信息 @Input() modal_info; // 发射隐藏modal的事件 @Output() hide_emitter = new EventEmitter(); constructor() {} ngOnInit() {} // 关闭modal框的事件 hideModal() { //将关闭modal的需求发射至父组件 this.hide_emitter.emit(emitted_info); } } ParentComponent.html <modal [modal_info]="parent_info" *ngIf="modal_control === 'child_name'" (hide_emitter)="getEmitter($event)"> ParentComponent.ts export class ParentComponent implements OnInit { //modal的默认显示状态是隐藏 private modal_control = ''; constructor() {} ngOnInit() {} // 显示modal showModal() { this.modal_control = 'child_name'; } //当初发modal的关闭事件,父组件接收到子组件发射的事件 getEmitter(event) { //接收到事件则说明modal需要隐藏 this.modal_control = event; } } 这是一种最简单的业务需求,但也是笔者实现复杂modal的基础原理 2.多个modal的处理在经历了最简单的父子关系之后,需求从独生子女家庭逐渐过度到了二胎政策开放。 <div *ngIf="modal_name === 'modal_one'"> ... </div> <div *ngIf="modal_name === 'modal_two'"> ... </div> 但这种个人认为这种写法并不是非常优雅,因为如果需要十个八个modal的时候,代码的维护性就会有所降低(至少看起来很烦人),于是想到是不是应该将每一个modal都做成一个component,这样既有利于html代码的整洁,也可以使ts中的代码更美观,更易维护。 ParentComponent.html <modal-one [modal_info]="modal_info_two"></modal-one> <modal-two [modal_info]="modal_info_one"></modal-two> 这样看起来好像是好了一点,但是比较丑的是在Parent的html文件末尾会堆下一堆modal的标签指令,所以笔者考虑了一种祖父-父-子结构的处理方式 <parent [modal_info_parent]="modal_info_grand" [modal_name_parent]="modal_name_grand"></parent> ParentComponent.html <modal-one [modal_info_child]="modal_info_parent" *ngIf="modal_name_parent ==='modal_child_one'"></modal-one> <modal-two [modal_info_child]="modal_info_parent" *ngIf="modal_name_parent ==='modal_child_two'"></modal-two> <modal-three [modal_info_child]="modal_info_parent" *ngIf="modal_name_parent ==='modal_child_threee'"></modal-three> 这样的技巧将每个modal分割开来,并将筛选modal的功能通过input属性从祖父组件传递到父组件,是父组件成为了一个单纯的变量传递者。到了这一步,其实也有一个问题:这样做是否太过与小题大作,因为父组件的额外添加,意味着变量的传递过程从父-子-父变成了祖父-父-子-父-祖父,为了完成这样的数据量可能要多些一大堆EventEmitter去发射数据。就现在看来,这种做法确实存在很大的冗余,但这种结构的用武之地并不是这样简单的组件关系 3.递归组件的modal处理angular4中修复了一个关于ngFor循环空数据而可能出现的死循环bug,这对于递归组件是一个好消息 假设我们需要显示一个树状结构的可展开式的带缩进下拉列表,由于每一个节点的ui本质上都是一样的,所以使用同一个component不停的递归调用自己是非常方便的,这时候我们我们加了一个需求,每一个节点都可以点击,弹出一个modal,用于修改该节点的信息,这个时候问题就来了,modal的应该写在哪,modal中该节点的数据从哪来。 <branch-data [tree]="parent_data"></branch-data> ChildComponent.html <div *ngFor="let child of tree"> <div>......</div> <div>......</div> <branch-data [tree]="child"></branch-data> </div> 这是一个非常典型的angular4中的树形结构数据递归显示的样例代码 无论哪一种方式,都涉及到另一种组件间传值的方式----service Modal.Service.ts export class ModalServcie { private modal_emitter = new EventEmitter(); constructor() { } getModalEmitter() { return this.modal_emitter; } emitModalName(modal_name) { this.modal_emitter.emit(modal_name); } } ModalComponent.ts export class ModalComponent implements OnInit { @Input() modal_name; constructor(private modalService: ModalService) { } hideModal() { this.modalService.emitModalName(''); } } ParentComponent.ts export class ParentComponent implements OnInit,OnDestroy { private modal_emitter; private modal_name = ''; constructor(private modalService: ModalService) { this.modal_emitter = this.modalService.getModalEmitter() .subscribe(data => { this.modal_name = data; }); } ngOnInit() { } ngOnDestroy() { this.modal_emitter.unsubscribe(); } showModal() { this.modal_name = 'child_name'; } } ParentComponent.html <modal [modal_name]='modal_name'></modal> modalComponent.html <child-modal [modal_name]='modal_name' *ngIf="modal_name === 'child_modal'"></child-modal> 上面的代码依靠服务,实现了一个三级子孙关系的数据传递 这种实现方法有如下好处
但这个方法也有一些需要斟酌的地方
this.http_emitter = this.yourService.getEmitter() .subscribe(data => { // 此时的data是你http请求流 data.subscribe(data1 => { // 此时的data1是http请求成功后返回的数据 }); }) 上面这种更新数据的方法,如果你没有在OnDestroy中注销EventEmitter的订阅的话,每次切换组件后再发射http的请求,你都会发现,单次请求实际触发的http数量在不断增加 好了,这次的总结分享就这么多了,希望对看文章的各位能有所帮助 也期待大家可以多多给予指点~多多交流~~~ ps:代码部分是纯手打的。。如果有什么错误还请大家指出并见谅。。。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |