Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(module:drawer): return componentRef when nzContent is a component #8339

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 20 additions & 17 deletions components/drawer/doc/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ import { NzDrawerModule } from 'ng-zorro-antd/drawer';
### nz-drawer:standalone

| Props | Description | Type | Default | Global Config |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | ----------- | ------------- |
|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------|-------------|---------------|
| `[nzClosable]` | Whether a close (x) button is visible on top left of the Drawer dialog or not. | `boolean` | `true` |
| `[nzCloseIcon]` | Custom close icon | `string \| TemplateRef<void> \| null` | `'close'` |
| `[nzExtra]` | Extra actions area at corner. | `string \| TemplateRef<void> \| null` | - |
| `[nzMask]` | Whether to show mask or not. | `boolean` | `true` | ✅ |
| `[nzMaskClosable]` | Clicking on the mask (area outside the Drawer) to close the Drawer or not. | `boolean` | `true` | ✅ |
| `[nzCloseOnNavigation]` | Whether to close the drawer when the user goes backwards/forwards in history. Note that this usually doesn't include clicking on links (unless the user is using the HashLocationStrategy). | `boolean` | `true` | ✅ |
| `[nzMask]` | Whether to show mask or not. | `boolean` | `true` | ✅ |
| `[nzMaskClosable]` | Clicking on the mask (area outside the Drawer) to close the Drawer or not. | `boolean` | `true` | ✅ |
| `[nzCloseOnNavigation]` | Whether to close the drawer when the user goes backwards/forwards in history. Note that this usually doesn't include clicking on links (unless the user is using the HashLocationStrategy). | `boolean` | `true` | ✅ |
| `[nzKeyboard]` | Whether support press esc to close | `boolean` | `true` |
| `[nzMaskStyle]` | Style for Drawer's mask element. | `object` | `{}` |
| `[nzBodyStyle]` | Body style for drawer body element. Such as height, padding etc. | `object` | `{}` |
Expand All @@ -52,24 +52,24 @@ import { NzDrawerModule } from 'ng-zorro-antd/drawer';
### NzDrawerService

| Method | Description | Params | Return |
| --------------- | ------------------------- | ----------------------- | ------------------- |
|-----------------|---------------------------|-------------------------|---------------------|
| create<T, D, R> | create and open an Drawer | `NzDrawerOptions<T, D>` | `NzDrawerRef<T, R>` |

### NzDrawerOptions

| Params | Description | Type | Default | Global Config |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | ----------- | ------------- |
|---------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------|-------------|---------------|
| nzContent | The drawer body content. | `TemplateRef<{ $implicit: D, drawerRef: NzDrawerRef }> \| Type<T>` | - |
| nzContentParams | Deprecated: Use NzData instead. The component inputs the param / The Template context | `D` | - |
| nzData | Will be a template variable when nzContent is TemplateRef. <br /> object, will be the value of the injection token NZ_MODAL_DATA when nzContent is a component | `D` | - |
| nzClosable | Whether a close (x) button is visible on top left of the Drawer dialog or not. | `boolean` | `true` |
| nzCloseIcon | Custom close icon | `string \| TemplateRef<void> \| null` | `'close'` |
| nzExtra | Extra actions area at corner. | `string \| TemplateRef<void> \| null` | - |
| nzOnCancel | Execute when click on the mask or the upper cancel button, This function returns a promise, which is automatically closed when the execution is complete or the promise ends (return false to prevent closing) | `() => Promise<any>` | - |
| nzMaskClosable | Clicking on the mask (area outside the Drawer) to close the Drawer or not. | `boolean` | `true` | ✅ |
| nzCloseOnNavigation | Whether to close the drawer when the user goes backwards/forwards in history. Note that this usually doesn't include clicking on links (unless the user is using the HashLocationStrategy). | `boolean` | `true` | ✅ |
| nzMask | Whether to show mask or not. | `boolean` | `true` | ✅ |
| nzDirection | Direction of the text in the modal | `'ltr' \| 'rtl'` | - | ✅ |
| nzMaskClosable | Clicking on the mask (area outside the Drawer) to close the Drawer or not. | `boolean` | `true` | ✅ |
| nzCloseOnNavigation | Whether to close the drawer when the user goes backwards/forwards in history. Note that this usually doesn't include clicking on links (unless the user is using the HashLocationStrategy). | `boolean` | `true` | ✅ |
| nzMask | Whether to show mask or not. | `boolean` | `true` | ✅ |
| nzDirection | Direction of the text in the modal | `'ltr' \| 'rtl'` | - | ✅ |
| nzKeyboard | Whether support press esc to close | `boolean` | `true` |
| nzMaskStyle | Style for Drawer's mask element. | `object` | `{}` |
| nzBodyStyle | Body style for modal body element. Such as height, padding etc. | `object` | `{}` |
Expand All @@ -86,22 +86,25 @@ import { NzDrawerModule } from 'ng-zorro-antd/drawer';

### NZ_DRAWER_DATA

NZ_DRAWER_DATA injection token is used to retrieve nzData in the custom component. The drawer created by the service method NzDrawerService.create() inject a NZ_DRAWER_DATA token (if nzContent is used as Component) to retrieve the parameters that have used to the 'nzContent component'
NZ_DRAWER_DATA injection token is used to retrieve nzData in the custom component. The drawer created by the service
method NzDrawerService.create() inject a NZ_DRAWER_DATA token (if nzContent is used as Component) to retrieve the
parameters that have used to the 'nzContent component'

### NzDrawerRef

#### Methods

| Name | Description | Type |
| ------------------- | ------------------------------------------------------- | ---------------------- |
| close | close the drawer. | `(result?: R) => void` |
| open | open the drawer. | `() => void` |
| getContentComponent | Returns the instance when `nzContent` is the component. | `() => T \| null` |
| Name | Description | Type |
|------------------------|---------------------------------------------------------------------------|---------------------------------|
| close | close the drawer. | `(result?: R) => void` |
| open | open the drawer. | `() => void` |
| getContentComponent | Returns the instance when `nzContent` is the component. | `() => T \| null` |
| getContentComponentRef | Returns the reference of the component when `nzContent` is the component. | `() => ComponentRef<T> \| null` |

#### Property

| Name | Description | Type |
| --------------- | ------------------------------------------------------------------------------- | ---------------------------------------- |
|-----------------|---------------------------------------------------------------------------------|------------------------------------------|
| afterOpen | Callback called after open. | `Observable<void>` |
| afterClose | Callback called after close. | `Observable<R>` |
| nzCloseIcon | Custom close icon | `string \| TemplateRef<void> \| null` |
Expand Down
3 changes: 2 additions & 1 deletion components/drawer/drawer-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/

import { TemplateRef } from '@angular/core';
import { ComponentRef, TemplateRef } from '@angular/core';
import { Observable } from 'rxjs';

import { NzSafeAny } from 'ng-zorro-antd/core/types';
Expand All @@ -16,6 +16,7 @@ export abstract class NzDrawerRef<T = NzSafeAny, R = NzSafeAny> {
abstract close(result?: R): void;
abstract open(): void;
abstract getContentComponent(): T | null;
abstract getContentComponentRef(): Readonly<ComponentRef<T>> | null;

abstract nzClosable?: boolean;
abstract nzNoAnimation?: boolean;
Expand Down
16 changes: 12 additions & 4 deletions components/drawer/drawer.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ComponentRef,
ContentChild,
EventEmitter,
Inject,
Expand Down Expand Up @@ -184,6 +185,7 @@ export class NzDrawerComponent<T extends {} = NzSafeAny, R = NzSafeAny, D extend
@Input() nzOffsetX = 0;
@Input() nzOffsetY = 0;
private componentInstance: T | null = null;
private componentRef: ComponentRef<T> | null = null;

@Input()
set nzVisible(value: boolean) {
Expand Down Expand Up @@ -387,6 +389,7 @@ export class NzDrawerComponent<T extends {} = NzSafeAny, R = NzSafeAny, D extend
this.nzAfterClose.next(result);
this.nzAfterClose.complete();
this.componentInstance = null;
this.componentRef = null;
}, this.getAnimationDuration());
}

Expand All @@ -412,6 +415,10 @@ export class NzDrawerComponent<T extends {} = NzSafeAny, R = NzSafeAny, D extend
return this.componentInstance;
}

override getContentComponentRef(): ComponentRef<T> | null {
return this.componentRef;
}

closeClick(): void {
this.nzOnClose.emit();
}
Expand All @@ -434,13 +441,14 @@ export class NzDrawerComponent<T extends {} = NzSafeAny, R = NzSafeAny, D extend
]
});
const componentPortal = new ComponentPortal<T>(this.nzContent, null, childInjector);
const componentRef = this.bodyPortalOutlet!.attachComponentPortal(componentPortal);
this.componentInstance = componentRef.instance;
this.componentRef = this.bodyPortalOutlet!.attachComponentPortal(componentPortal);

this.componentInstance = this.componentRef.instance;
/**TODO
* When nzContentParam will be remove in the next major version, we have to remove the following line
* **/
Object.assign(componentRef.instance!, this.nzData || this.nzContentParams);
componentRef.changeDetectorRef.detectChanges();
Object.assign(this.componentRef.instance!, this.nzData || this.nzContentParams);
this.componentRef.changeDetectorRef.detectChanges();
}
}

Expand Down
5 changes: 5 additions & 0 deletions components/drawer/drawer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,7 @@ describe('NzDrawerService', () => {
fixture.detectChanges();
tick(300);
expect(component.templateDrawerRef?.getContentComponent()).toBeNull();
expect(component.templateDrawerRef?.getContentComponentRef()).toBeNull();
expect(component.templateOpenSpy).toHaveBeenCalled();
fixture.detectChanges();
(overlayContainerElement.querySelector('.ant-drawer .ant-drawer-mask') as HTMLElement).click();
Expand All @@ -719,6 +720,7 @@ describe('NzDrawerService', () => {
fixture.detectChanges();
expect(openSpy).not.toHaveBeenCalled();
expect(drawerRef.getContentComponent()).not.toBeNull();
expect(drawerRef.getContentComponentRef()).not.toBeNull();
tick(300);
expect(openSpy).toHaveBeenCalled();
(overlayContainerElement.querySelector('.ant-drawer .close-btn') as HTMLElement).click();
Expand All @@ -727,6 +729,7 @@ describe('NzDrawerService', () => {
expect(closeSpy).toHaveBeenCalled();
fixture.detectChanges();
expect(drawerRef.getContentComponent()).toBeNull();
expect(drawerRef.getContentComponentRef()).toBeNull();
}));

it('should create a component drawer and use nzData instead of nzContentParams', fakeAsync(() => {
Expand All @@ -744,6 +747,7 @@ describe('NzDrawerService', () => {
fixture.detectChanges();
expect(openSpy).not.toHaveBeenCalled();
expect(drawerRef.getContentComponent()).not.toBeNull();
expect(drawerRef.getContentComponentRef()).not.toBeNull();
tick(300);
expect(openSpy).toHaveBeenCalled();
(overlayContainerElement.querySelector('.ant-drawer .close-btn') as HTMLElement).click();
Expand All @@ -752,6 +756,7 @@ describe('NzDrawerService', () => {
expect(closeSpy).toHaveBeenCalled();
fixture.detectChanges();
expect(drawerRef.getContentComponent()).toBeNull();
expect(drawerRef.getContentComponentRef()).toBeNull();
}));

it('should `nzOnCancel` work', fakeAsync(() => {
Expand Down