Skip to content

Commit

Permalink
fix(modal): make it easier to use components from lazy-loaded modules
Browse files Browse the repository at this point in the history
Fixes #947
Closes #974
  • Loading branch information
pkozlowski-opensource committed Oct 27, 2016
1 parent 9b5f999 commit 2fb72d8
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 11 deletions.
8 changes: 4 additions & 4 deletions src/modal/modal-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ export class NgbModalContainer {
ngbModalStack.registerContainer(this);
}

open(content: string | TemplateRef<any>, options): NgbModalRef {
open(moduleCFR: ComponentFactoryResolver, content: string | TemplateRef<any>, options): NgbModalRef {
const activeModal = new NgbActiveModal();
const contentRef = this._getContentRef(content, activeModal);
const contentRef = this._getContentRef(moduleCFR, content, activeModal);
let windowCmptRef: ComponentRef<NgbModalWindow>;
let backdropCmptRef: ComponentRef<NgbModalBackdrop>;
let ngbModalRef: NgbModalRef;
Expand Down Expand Up @@ -65,7 +65,7 @@ export class NgbModalContainer {
});
}

private _getContentRef(content: any, context: NgbActiveModal): ContentRef {
private _getContentRef(moduleCFR: ComponentFactoryResolver, content: any, context: NgbActiveModal): ContentRef {
if (!content) {
return new ContentRef([]);
} else if (content instanceof TemplateRef) {
Expand All @@ -74,7 +74,7 @@ export class NgbModalContainer {
} else if (isString(content)) {
return new ContentRef([[this._renderer.createText(null, `${content}`)]]);
} else {
const contentCmptFactory = this._componentFactoryResolver.resolveComponentFactory(content);
const contentCmptFactory = moduleCFR.resolveComponentFactory(content);
const modalContentInjector =
ReflectiveInjector.resolveAndCreate([{provide: NgbActiveModal, useValue: context}], this._injector);
const componentRef = this._viewContainerRef.createComponent(contentCmptFactory, 0, modalContentInjector);
Expand Down
2 changes: 1 addition & 1 deletion src/modal/modal-stack.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ describe('modal stack', () => {

it('should throw if a container element was not registered', () => {
const modalStack = new NgbModalStack();
expect(() => { modalStack.open('foo'); }).toThrowError();
expect(() => { modalStack.open(null, 'foo'); }).toThrowError();
});
});
6 changes: 3 additions & 3 deletions src/modal/modal-stack.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Injectable, TemplateRef} from '@angular/core';
import {Injectable, ComponentFactoryResolver} from '@angular/core';

import {NgbModalRef} from './modal-ref';
import {NgbModalContainer} from './modal-container';
Expand All @@ -7,13 +7,13 @@ import {NgbModalContainer} from './modal-container';
export class NgbModalStack {
private modalContainer: NgbModalContainer;

open(content: any, options = {}): NgbModalRef {
open(moduleCFR: ComponentFactoryResolver, content: any, options = {}): NgbModalRef {
if (!this.modalContainer) {
throw new Error(
'Missing modal container, add <template ngbModalContainer></template> to one of your application templates.');
}

return this.modalContainer.open(content, options);
return this.modalContainer.open(moduleCFR, content, options);
}

registerContainer(modalContainer: NgbModalContainer) { this.modalContainer = modalContainer; }
Expand Down
1 change: 1 addition & 0 deletions src/modal/modal.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export {ModalDismissReasons} from './modal-dismiss-reasons';
@NgModule({
declarations: [NgbModalContainer, NgbModalBackdrop, NgbModalWindow],
entryComponents: [NgbModalBackdrop, NgbModalWindow],
providers: [NgbModal],
exports: [NgbModalContainer]
})
export class NgbModalModule {
Expand Down
8 changes: 5 additions & 3 deletions src/modal/modal.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Injectable, TemplateRef} from '@angular/core';
import {Injectable, ComponentFactoryResolver} from '@angular/core';

import {NgbModalStack} from './modal-stack';
import {NgbModalRef} from './modal-ref';
Expand Down Expand Up @@ -35,13 +35,15 @@ export interface NgbModalOptions {
*/
@Injectable()
export class NgbModal {
constructor(private _modalStack: NgbModalStack) {}
constructor(private _moduleCFR: ComponentFactoryResolver, private _modalStack: NgbModalStack) {}

/**
* Opens a new modal window with the specified content and using supplied options. Content can be provided
* as a TemplateRef or a component type. If you pass a component type as content than instances of those
* components can be injected with an instance of the NgbActiveModal class. You can use methods on the
* NgbActiveModal class to close / dismiss modals from "inside" of a component.
*/
open(content: any, options: NgbModalOptions = {}): NgbModalRef { return this._modalStack.open(content, options); }
open(content: any, options: NgbModalOptions = {}): NgbModalRef {
return this._modalStack.open(this._moduleCFR, content, options);
}
}

0 comments on commit 2fb72d8

Please sign in to comment.