diff --git a/components/message/doc/index.en-US.md b/components/message/doc/index.en-US.md index c9283f53cc1..73d86014cb8 100644 --- a/components/message/doc/index.en-US.md +++ b/components/message/doc/index.en-US.md @@ -41,7 +41,7 @@ This components provides some service methods, with usage and arguments as follo | Argument | Description | Type | Default | | -------- | ----------- | ---- | ------- | -| content | The content of message | `string` | - | +| content | The content of message | `string|TemplateRef` | - | | options | Support setting the parameters for the current message box, see the table below | `object` | - | The parameters that are set by the `options` support are as follows: diff --git a/components/message/doc/index.zh-CN.md b/components/message/doc/index.zh-CN.md index d37ea73081b..c1122c49ef7 100644 --- a/components/message/doc/index.zh-CN.md +++ b/components/message/doc/index.zh-CN.md @@ -42,7 +42,7 @@ title: Message | 参数 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | -| content | 提示内容 | `string` | - | +| content | 提示内容 | `string|TemplateRef` | - | | options | 支持设置针对当前提示框的参数,见下方表格 | `object` | - | `options` 支持设置的参数如下: diff --git a/components/message/nz-message.component.html b/components/message/nz-message.component.html index 340be5fd60a..dae69170bf3 100644 --- a/components/message/nz-message.component.html +++ b/components/message/nz-message.component.html @@ -11,7 +11,9 @@ - + + + - \ No newline at end of file + diff --git a/components/message/nz-message.definitions.ts b/components/message/nz-message.definitions.ts index 440baaa1643..92fc6f7d6c0 100644 --- a/components/message/nz-message.definitions.ts +++ b/components/message/nz-message.definitions.ts @@ -1,3 +1,4 @@ +import { TemplateRef } from '@angular/core'; import { Subject } from 'rxjs'; export type NzMessageType = 'success' | 'info' | 'warning' | 'error' | 'loading'; @@ -13,7 +14,7 @@ export interface NzMessageDataOptions { */ export interface NzMessageData { type?: NzMessageType | string; - content?: string; + content?: string | TemplateRef; } /** diff --git a/components/message/nz-message.module.ts b/components/message/nz-message.module.ts index 9fb3552b026..f797cb3d3fe 100644 --- a/components/message/nz-message.module.ts +++ b/components/message/nz-message.module.ts @@ -1,6 +1,7 @@ import { OverlayModule } from '@angular/cdk/overlay'; import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; +import { NzAddOnModule } from '../core/addon/addon.module'; import { NzIconModule } from '../icon/nz-icon.module'; import { NZ_MESSAGE_DEFAULT_CONFIG_PROVIDER } from './nz-message-config'; @@ -9,7 +10,7 @@ import { NzMessageComponent } from './nz-message.component'; import { NzMessageService } from './nz-message.service'; @NgModule({ - imports : [ CommonModule, OverlayModule, NzIconModule ], + imports : [ CommonModule, OverlayModule, NzIconModule, NzAddOnModule ], declarations : [ NzMessageContainerComponent, NzMessageComponent ], providers : [ NZ_MESSAGE_DEFAULT_CONFIG_PROVIDER, NzMessageService ], entryComponents: [ NzMessageContainerComponent ] diff --git a/components/message/nz-message.service.ts b/components/message/nz-message.service.ts index 9f7063aa12e..5ff054b08d2 100644 --- a/components/message/nz-message.service.ts +++ b/components/message/nz-message.service.ts @@ -1,5 +1,5 @@ import { Overlay } from '@angular/cdk/overlay'; -import { ApplicationRef, ComponentFactoryResolver, EmbeddedViewRef, Injectable, Injector, Type } from '@angular/core'; +import { ApplicationRef, ComponentFactoryResolver, EmbeddedViewRef, Injectable, Injector, TemplateRef, Type } from '@angular/core'; import { NzMessageConfig } from './nz-message-config'; import { NzMessageContainerComponent } from './nz-message-container.component'; @@ -7,7 +7,11 @@ import { NzMessageData, NzMessageDataFilled, NzMessageDataOptions } from './nz-m let globalCounter = 0; -export class NzMessageBaseService { +export class NzMessageBaseService< + ContainerClass extends NzMessageContainerComponent, + MessageData, + MessageConfig extends NzMessageConfig +> { protected _container: ContainerClass; constructor( @@ -31,11 +35,11 @@ export class NzMessageBaseService, options?: NzMessageDataOptions): NzMessageDataFilled { return this.createMessage({ type: 'success', content }, options); } - error(content: string, options?: NzMessageDataOptions): NzMessageDataFilled { + error(content: string | TemplateRef, options?: NzMessageDataOptions): NzMessageDataFilled { return this.createMessage({ type: 'error', content }, options); } - info(content: string, options?: NzMessageDataOptions): NzMessageDataFilled { + info(content: string | TemplateRef, options?: NzMessageDataOptions): NzMessageDataFilled { return this.createMessage({ type: 'info', content }, options); } - warning(content: string, options?: NzMessageDataOptions): NzMessageDataFilled { + warning(content: string | TemplateRef, options?: NzMessageDataOptions): NzMessageDataFilled { return this.createMessage({ type: 'warning', content }, options); } - loading(content: string, options?: NzMessageDataOptions): NzMessageDataFilled { + loading(content: string | TemplateRef, options?: NzMessageDataOptions): NzMessageDataFilled { return this.createMessage({ type: 'loading', content }, options); } - create(type: 'success' | 'info' | 'warning' | 'error' | 'loading' | string, content: string, options?: NzMessageDataOptions): NzMessageDataFilled { + create( + type: 'success' | 'info' | 'warning' | 'error' | 'loading' | string, + content: string | TemplateRef, + options?: NzMessageDataOptions + ): NzMessageDataFilled { return this.createMessage({ type, content }, options); } } diff --git a/components/message/nz-message.spec.ts b/components/message/nz-message.spec.ts index 5a56f30922f..fbaf0eb776e 100644 --- a/components/message/nz-message.spec.ts +++ b/components/message/nz-message.spec.ts @@ -1,6 +1,6 @@ import { OverlayContainer } from '@angular/cdk/overlay'; -import { Component } from '@angular/core'; +import { Component, TemplateRef, ViewChild } from '@angular/core'; import { fakeAsync, inject, tick, ComponentFixture, TestBed } from '@angular/core/testing'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; @@ -14,7 +14,8 @@ describe('NzMessage', () => { let messageService: NzMessageService; let overlayContainer: OverlayContainer; let overlayContainerElement: HTMLElement; - let demoAppFixture: ComponentFixture; + let fixture: ComponentFixture; + let testComponent: NzTestMessageBasicComponent; beforeEach(fakeAsync(() => { TestBed.configureTestingModule({ @@ -37,12 +38,13 @@ describe('NzMessage', () => { }); beforeEach(() => { - demoAppFixture = TestBed.createComponent(NzTestMessageBasicComponent); + fixture = TestBed.createComponent(NzTestMessageBasicComponent); + testComponent = fixture.debugElement.componentInstance; }); it('should open a message box with success', (() => { messageService.success('SUCCESS'); - demoAppFixture.detectChanges(); + fixture.detectChanges(); expect((overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement).style.zIndex).toBe('1010'); expect(overlayContainerElement.textContent).toContain('SUCCESS'); @@ -51,7 +53,7 @@ describe('NzMessage', () => { it('should open a message box with error', (() => { messageService.error('ERROR'); - demoAppFixture.detectChanges(); + fixture.detectChanges(); expect(overlayContainerElement.textContent).toContain('ERROR'); expect(overlayContainerElement.querySelector('.anticon-close-circle')).not.toBeNull(); @@ -59,7 +61,7 @@ describe('NzMessage', () => { it('should open a message box with warning', (() => { messageService.warning('WARNING'); - demoAppFixture.detectChanges(); + fixture.detectChanges(); expect(overlayContainerElement.textContent).toContain('WARNING'); expect(overlayContainerElement.querySelector('.anticon-exclamation-circle')).not.toBeNull(); @@ -67,7 +69,7 @@ describe('NzMessage', () => { it('should open a message box with info', (() => { messageService.info('INFO'); - demoAppFixture.detectChanges(); + fixture.detectChanges(); expect(overlayContainerElement.textContent).toContain('INFO'); expect(overlayContainerElement.querySelector('.anticon-info-circle')).not.toBeNull(); @@ -75,15 +77,23 @@ describe('NzMessage', () => { it('should open a message box with loading', (() => { messageService.loading('LOADING'); - demoAppFixture.detectChanges(); + fixture.detectChanges(); expect(overlayContainerElement.textContent).toContain('LOADING'); expect(overlayContainerElement.querySelector('.anticon-loading')).not.toBeNull(); })); + it('should support template', fakeAsync(() => { + messageService.info(testComponent.template); + fixture.detectChanges(); + + expect(overlayContainerElement.textContent).toContain('Content in template'); + tick(10000); + })); + it('should auto closed by 1s', fakeAsync(() => { messageService.create('', 'EXISTS', { nzDuration: 1000 }); - demoAppFixture.detectChanges(); + fixture.detectChanges(); expect(overlayContainerElement.textContent).toContain('EXISTS'); @@ -93,7 +103,7 @@ describe('NzMessage', () => { it('should not destroy when hovered', fakeAsync(() => { messageService.create('', 'EXISTS', { nzDuration: 3000 }); - demoAppFixture.detectChanges(); + fixture.detectChanges(); const messageElement = overlayContainerElement.querySelector('.ant-message-notice')!; dispatchMouseEvent(messageElement, 'mouseenter'); @@ -107,13 +117,13 @@ describe('NzMessage', () => { it('should not destroyed automatically but manually', fakeAsync(() => { const filledMessage = messageService.success('SUCCESS', { nzDuration: 0 }); - demoAppFixture.detectChanges(); + fixture.detectChanges(); tick(50000); expect(overlayContainerElement.textContent).toContain('SUCCESS'); messageService.remove(filledMessage.messageId); - demoAppFixture.detectChanges(); + fixture.detectChanges(); expect(overlayContainerElement.textContent).not.toContain('SUCCESS'); })); @@ -121,9 +131,9 @@ describe('NzMessage', () => { [ 1, 2, 3 ].forEach(id => { const content = `SUCCESS-${id}`; messageService.success(content); - demoAppFixture.detectChanges(); + fixture.detectChanges(); tick(); - demoAppFixture.detectChanges(); + fixture.detectChanges(); expect(overlayContainerElement.textContent).toContain(content); if (id === 3) { @@ -133,14 +143,14 @@ describe('NzMessage', () => { }); messageService.remove(); - demoAppFixture.detectChanges(); + fixture.detectChanges(); expect(overlayContainerElement.textContent).not.toContain('SUCCESS-3'); expect((messageService as any)._container.messages.length).toBe(0); // tslint:disable-line:no-any })); it('should destroy without animation', fakeAsync(() => { messageService.error('EXISTS', { nzDuration: 1000, nzAnimate: false }); - demoAppFixture.detectChanges(); + fixture.detectChanges(); tick(1000 + 10); expect(overlayContainerElement.textContent).not.toContain('EXISTS'); })); @@ -148,7 +158,7 @@ describe('NzMessage', () => { it('should reset default config dynamically', fakeAsync(() => { messageService.config({ nzDuration: 0 }); messageService.create('loading', 'EXISTS'); - demoAppFixture.detectChanges(); + fixture.detectChanges(); tick(1000); expect(overlayContainerElement.textContent).toContain('EXISTS'); })); @@ -159,14 +169,15 @@ describe('NzMessage', () => { msg.onClose!.subscribe(() => { onCloseFlag = true; }); - demoAppFixture.detectChanges(); + + fixture.detectChanges(); tick(50000); expect(onCloseFlag).toBeTruthy(); })); it('should container top to configured', fakeAsync(() => { messageService.create('top', 'CHANGE'); - demoAppFixture.detectChanges(); + fixture.detectChanges(); const messageContainerElement = overlayContainerElement.querySelector('.ant-message') as HTMLElement; expect(messageContainerElement.style.top).toBe('24px'); @@ -177,6 +188,12 @@ describe('NzMessage', () => { @Component({ selector: 'nz-demo-app-component', - template: `` + template: ` + + Content in template + + ` }) -export class NzTestMessageBasicComponent {} +export class NzTestMessageBasicComponent { + @ViewChild('contentTemplate') template: TemplateRef; +}