Closed Tahiche closed 6 years ago
ok so i'll be honest i'm still digesting your implementation but if i was to take what i think i understand as your requirement you want the ability to do something like this
import { Component, ViewChild } from '@angular/core';
import { BsModalComponent } from 'ng2-bs3-modal';
@Component({
selector: 'parent-component',
template: `
<bs-modal #myModal>
...
</bs-modal>
`
})
export class ParentComponent {
@ViewChild('myModal')
modal: BsModalComponent;
close() {
this.modal.close();
}
open() {
this.modal.open();
}
}
Hi, thanks for the response. Yes, your example from 'ng2-bs3-modal' is the kind of implementation I´m after. I´m sorry if i wasn´t clear enough. Since ngx-simple-modal does it´s magic through ComponentFactoryResolver my approach was to sort of mimic modalHolderComponent/wrapper... read the content of the child modal ('bs-modal' in your example) and pass it to a "holder" component via the service... ng-bootstrap modal has this option of opening a component modal via service or a modal in the template/dom.
This might be totally worng or overhead... I tried getting this "component markup" (templateRef) into "message" but I can´´t get message to render the html... Bassically, it´s just getting a modal to open markup on the page/template...
As for my approach, it´s actually working except this.modalService.modalHolderComponent is private , sometimes it works, sometimes it gives me an error.
Thanks for your patience...
I managed to close the opened modal via suscriber which looks like an OK approach... (I´m a noop at suscribers and promises)...
Code in parent template modal.component.html:
<button type="button" class="btn btn-default" (click)="domModal.open()">Open
<b>modal</b> in dom.</button>
<div *ngIf="modalAction != null">
<span>Result: </span>
<b [ngClass]="{'text-warning': modalAction=='DISMISSED'?true:false, 'text-success': modalAction==('CLOSED' || 'OPEN')?true:false}">{{modalAction}}</b>
</div>
<modal
(onOpen)="modalAction='OPEN'"
(onClose)="modalAction='CLOSED'"
(onDismiss)="modalAction='DISMISSED'"
title="Modal title"
#domModal>
<modal-header>Hi this is head of modal.
<b>Bold</b>
</modal-header>
Modal body here.... this is the first modal.
<input type="text" evInput evIcon="fa-android" [(ngModel)]="inputText" />
<modal-footer>Hi this is modal footer.
<button class="btn btn-success" (click)="modalInnerSubmit(domModal)">InnerSubmit</button>
</modal-footer>
</modal>
modal.component.ts
...
modalAction = null;
modalInnerSubmit(modal: SimpleModalComponent<any, any>) {
alert('modalInnerSubmit');
modal.close();
}
dom-modal.component.ts
@Component({
selector: 'modal',
template: `<ng-template #domModalContent>
<ng-content ></ng-content>
</ng-template>
<ng-template #footer >
<ng-content select="modal-footer"></ng-content>
</ng-template>
<ng-template #header >
<ng-content select="modal-header"></ng-content>
</ng-template>`
})
export class DomModalComponent extends BaseModalComponent implements GenericModalModel, OnInit, OnDestroy {
@ViewChild('domModalContent') content: TemplateRef<any>;
@ViewChild('footer') footer: TemplateRef<any>;
@ViewChild('header') header: TemplateRef<any>;
@Output() onClose: EventEmitter<any> = new EventEmitter(false);
@Output() onDismiss: EventEmitter<any> = new EventEmitter(false);
@Output() onOpen: EventEmitter<any> = new EventEmitter(false);
openM: Observable<any>;
modalIndex: number;
openModal: SimpleModalService;
public openedModalResult: any = null;
modalAction: EventEmitter<any> = new EventEmitter();
suscriber;
constructor(private modalService: SimpleModalService,
private _componentFactoryResolver: ComponentFactoryResolver) {
super();
}
close(): Promise<any> {
// this.suscriber.next(true);
this.suscriber.unsubscribe();
this.onClose.emit(true);
return new Promise((resolve, reject) => resolve(true) );
}
dismiss() {
this.suscriber.unsubscribe();
this.onClose.emit(false);
return new Promise((resolve, reject) => resolve(false) );
}
open() {
// how many of this.properties are attributes to pass along to creation?
const attrObject = this.attributesToObject() || {};
this.suscriber = this.modalService.addModal(GenericModalComponent,
{...attrObject},
{closeOnClickOutside: true}
).subscribe((modalResult) => {
this.openedModalResult = modalResult || null;
this.modalAction.emit(this.openedModalResult);
if (modalResult) {
// this.close();
this.onClose.emit(true);
} else if (modalResult === false) {
this.onDismiss.emit(null);
} else {
this.onClose.emit(modalResult || null);
}
});
this.onOpen.emit(true);
}
attributesToObject() {
const availableAttrs = Object.keys(this);
// attributes we want to parse...
const attrObject = new GenericModalModelClass();
for (const attr of Object.keys(attrObject)) {
if (this[attr]) {
attrObject[attr] = this[attr];
}
}
return attrObject;
}
}
Yeah, i like this idea, I think I can make this simpler for you too long term. The only issue I have right this second is that I'm only 3 weeks into my new role so I'm being conservative with my time. I'll try to carve out some time to write something to help support you more. Meanwhle looks like you've found a route through.
Going to close this for now - its a bit of a different direction tbh from where the component is. I'll revisit it further on.
Apologies in advance, this is not an issue but a support request... I love this lib, it´s great for most use cases. I´m just missing the option for a more "specific" use case when you don´t want to create a component (extending SimpleModalComponent) but rather just include it in your parent component. This is the way other libs (for ex Angular Bootstrap 3 Modal Component work. I´d really like to have the best of both worlds, have components for alerts, confirms, etc as you do but also to pull the modal from DOM in a more Bootstrapish approach.
My approach to do this is to create a "DomComponent" with "" selector that in turn calls SimpleModalService to open it´s content (through a GenericModalComponent). I´ll post the code i´m using, but it might be a totally wrong approach, so I can point out the problems i´m encountering....
In parent component ....
And DomModal component: (BaseModalComponent extends SimpleModalComponent).
I have major issues here. I can open the modal just fine using Service. But i have no reference to the opened Modal, the only way i can seem to access it is by " this.modalService.modalHolderComponent.modals;" which seems wrong and even more since it´s a private var. I implemented "closerCallback" to be able to extend, since DomModal is not opened through service... here is where i close the opened modal... But "this.modalService.removeModal();" needs the opened modal which i can´t seem to target, so I hackishly target modalHolderComponent to get the last opened modal. There must be a better way (for sure ;) and even if my approach is halfway alright (doubt it) there must be a way of interacting (closing, etc) with the opened modal through Promises, Observables... Triggering the opened modal close() and resolving without direct ref to modalHolderComponent....
I´d really love to implement this to cover all cases. Thanks in advance!!.