angular - 在所有组件之间共享模态
angular - share modal across all components
我正在尝试实现自定义 确认对话框 功能,该功能计划在所有组件中在应用程序范围内提供。
为此我使用 Angular Material
.
模态是一个单独的组件,我通过以下方式在另一个组件中解析它:
const dialogRef = this.confirmDialog.open(ConfirmDialogComponent, ... });
我面临的问题 - 使用这种方法我必须在每个组件中复制代码。 DRY principle
被违反了。
更多详情:
...
export class SearchComponent extends AppComponentBase {...
constructor(public confirmDialog: MatDialog, ...) { super(injector); }
confirm(title: string, message: string) {
var promise = new Promise((resolve, reject) => {
const dialogRef = this.confirmDialog.open(ConfirmDialogComponent, {
width: '250px',
data: { title: title, message: message }
});
dialogRef.afterClosed().subscribe(result => {
if (result) {
resolve();
} else {
reject();
}
});
});
return promise;
}
显然我可以将共享代码移至基本组件 - AppComponentBase
。尽管仍然会有一些重复的代码——例如构造函数相关代码。
但是,在软件设计方面是否有更好/更简洁的方法来重构我所拥有的?
谢谢。
一个工作示例StackBlitz
将其放在根级别的 /shared 或 /services 文件夹中。
服务:
import { Observable } from 'rxjs';
import { MessagesComponent } from './messages.component';
import { MatDialogRef, MatDialog } from '@angular/material';
import { Injectable } from '@angular/core';
@Injectable()
export class MessagesService {
dialogRef: MatDialogRef<MessagesComponent>;
constructor(private dialog: MatDialog) { }
public openDialog(title: string, message: string): Observable<any> {
this.dialogRef = this.dialog.open(MessagesComponent);
this.dialogRef.componentInstance.title = title;
this.dialogRef.componentInstance.message = message;
return this.dialogRef.afterClosed();
// Nothing can live after afterClosed.
}
}
component.ts
import { Component, OnInit } from '@angular/core';
import { MatDialogRef } from '@angular/material';
@Component({
selector: 'app-messages',
templateUrl: './messages.component.html'
})
export class MessagesComponent implements OnInit {
public title: string;
public message: string;
constructor(
private dialogRef: MatDialogRef<MessagesComponent>,
) { }
private closeWithTimer() {
setTimeout (() => {
this.dialogRef.close();
}, 2000);
}
ngOnInit() {
this.closeWithTimer();
}
}
html:
<h1 mat-dialog-title>{{title}}!</h1>
<div mat-dialog-content>{{message}}</div>
从您的 Universe 中的某个组件调用:
constructor(
private httpService: HttpService,
public dialogRef: MatDialogRef<AddMemberComponent>, // Used by the html component.
private messagesService: MessagesService,
public formErrorsService: FormErrorsService
) { }
this.httpService.addRecord(this.membersUrl, enteredData)
.subscribe(
res => {
this.success();
},
(err: HttpErrorResponse) => {
console.log(err.error);
console.log(err.message);
this.handleError(err);
}
);
在该组件的底部:
private success() {
this.messagesService.openDialog('Success', 'Database updated as you wished!');
}
private handleError(error) {
this.messagesService.openDialog('Error addm1', 'Please check your Internet connection.');
}
我正在尝试实现自定义 确认对话框 功能,该功能计划在所有组件中在应用程序范围内提供。
为此我使用 Angular Material
.
模态是一个单独的组件,我通过以下方式在另一个组件中解析它:
const dialogRef = this.confirmDialog.open(ConfirmDialogComponent, ... });
我面临的问题 - 使用这种方法我必须在每个组件中复制代码。 DRY principle
被违反了。
更多详情:
...
export class SearchComponent extends AppComponentBase {...
constructor(public confirmDialog: MatDialog, ...) { super(injector); }
confirm(title: string, message: string) {
var promise = new Promise((resolve, reject) => {
const dialogRef = this.confirmDialog.open(ConfirmDialogComponent, {
width: '250px',
data: { title: title, message: message }
});
dialogRef.afterClosed().subscribe(result => {
if (result) {
resolve();
} else {
reject();
}
});
});
return promise;
}
显然我可以将共享代码移至基本组件 - AppComponentBase
。尽管仍然会有一些重复的代码——例如构造函数相关代码。
但是,在软件设计方面是否有更好/更简洁的方法来重构我所拥有的?
谢谢。
一个工作示例StackBlitz
将其放在根级别的 /shared 或 /services 文件夹中。
服务:
import { Observable } from 'rxjs';
import { MessagesComponent } from './messages.component';
import { MatDialogRef, MatDialog } from '@angular/material';
import { Injectable } from '@angular/core';
@Injectable()
export class MessagesService {
dialogRef: MatDialogRef<MessagesComponent>;
constructor(private dialog: MatDialog) { }
public openDialog(title: string, message: string): Observable<any> {
this.dialogRef = this.dialog.open(MessagesComponent);
this.dialogRef.componentInstance.title = title;
this.dialogRef.componentInstance.message = message;
return this.dialogRef.afterClosed();
// Nothing can live after afterClosed.
}
}
component.ts
import { Component, OnInit } from '@angular/core';
import { MatDialogRef } from '@angular/material';
@Component({
selector: 'app-messages',
templateUrl: './messages.component.html'
})
export class MessagesComponent implements OnInit {
public title: string;
public message: string;
constructor(
private dialogRef: MatDialogRef<MessagesComponent>,
) { }
private closeWithTimer() {
setTimeout (() => {
this.dialogRef.close();
}, 2000);
}
ngOnInit() {
this.closeWithTimer();
}
}
html:
<h1 mat-dialog-title>{{title}}!</h1>
<div mat-dialog-content>{{message}}</div>
从您的 Universe 中的某个组件调用:
constructor(
private httpService: HttpService,
public dialogRef: MatDialogRef<AddMemberComponent>, // Used by the html component.
private messagesService: MessagesService,
public formErrorsService: FormErrorsService
) { }
this.httpService.addRecord(this.membersUrl, enteredData)
.subscribe(
res => {
this.success();
},
(err: HttpErrorResponse) => {
console.log(err.error);
console.log(err.message);
this.handleError(err);
}
);
在该组件的底部:
private success() {
this.messagesService.openDialog('Success', 'Database updated as you wished!');
}
private handleError(error) {
this.messagesService.openDialog('Error addm1', 'Please check your Internet connection.');
}