我是Angular的新手,对服务有疑问。过去,我会使用其他语言来创建自包含的组件,这些组件可以从应用程序中的任何位置调用。
我需要以模态显示的弹出对话框和错误消息,可以从其他服务或组件的ts文件调用该消息。
我的最终目标是不要将对话框的HTML包含在多个组件中,而是将其包含在单个服务或组件与服务中。
我最初的想法是,服务的内容完全独立,如果模板和样式部分(如果在服务中可用),或者完全无效,则使用带有对话框方法的服务以及包含标记和样式的单独组件。
我在想的是2个想法之一: 1.一种具有必要的html,样式和方法以显示对话框或错误消息的服务 2.一起显示对话框的服务和组件
我是用这种思路走在正确的道路上吗?还是在考虑做一些会咬我的事情?
答案 0 :(得分:0)
使用服务封装Angular对话框逻辑是一种很好的方法。利用Angular Material Dialog,您可以按以下方式创建服务。
import { ElementRef, Injectable } from '@angular/core'
import { MatDialog, MatDialogRef } from '@angular/material'
import { DialogProfileOptionsComponent } from './dialog-profile-options/dialog-profile-options.component'
import { DialogYesNoComponent } from './dialog-yes-no/dialog-yes-no.component'
@Injectable({
providedIn: 'root'
})
export class DialogService {
constructor(public dialog: MatDialog) { }
public open_info_dialog() { }
public open_profile_options_dialog({ position_relative_to_element, user,
has_backdrop = false, height = '135px', width = '290px' }:
{
position_relative_to_element: ElementRef, user: firebase.User, has_backdrop?: boolean,
height?: string, width?: string
}): MatDialogRef<DialogProfileOptionsComponent> {
const dialog_ref: MatDialogRef<DialogProfileOptionsComponent> =
this.dialog.open(DialogProfileOptionsComponent, {
hasBackdrop: has_backdrop,
height: height,
width: width,
data: { position_relative_to_element: position_relative_to_element, user: user }
})
return dialog_ref
}
public open_yes_no_dialog({ question, title = 'Confirm', yes_button_first = true,
has_backdrop = false, height = '250px', width = '350px' }:
{
question: string, title?: string, yes_button_first?: boolean, has_backdrop?: boolean,
height?: string, width?: string
}): MatDialogRef<DialogYesNoComponent> {
const dialog_ref = this.dialog.open(DialogYesNoComponent, {
autoFocus: true,
backdropClass: 'cdk-overlay-transparent-backdrop',
closeOnNavigation: true,
disableClose: false,
hasBackdrop: has_backdrop,
height: height,
width: width,
data: { question: question, title: title, yes_button_first: yes_button_first }
})
return dialog_ref
}
open_warning_dialog() { /* TODO */ }
}
import { Component, ElementRef, Inject, OnInit } from '@angular/core'
import { MatDialogConfig, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'
@Component({
selector: 'dialog-profile-options',
templateUrl: './dialog-profile-options.component.html',
styleUrls: ['./dialog-profile-options.component.css']
})
export class DialogProfileOptionsComponent implements OnInit {
private position_relative_to_element: ElementRef
constructor(public dialog_ref: MatDialogRef<DialogProfileOptionsComponent>,
@Inject(MAT_DIALOG_DATA) public options: { position_relative_to_element: ElementRef,
user: firebase.User }) {
this.position_relative_to_element = options.position_relative_to_element
}
ngOnInit() {
const mat_dialog_config = new MatDialogConfig()
const rect: DOMRect = this.position_relative_to_element.nativeElement.getBoundingClientRect()
mat_dialog_config.position = { right: `10px`, top: `${rect.bottom + 2}px` }
this.dialog_ref.updatePosition(mat_dialog_config.position)
}
}
<div mat-dialog-content>
<div><b>{{options.user.displayName}}</b></div>
<div class="text-secondary">{{options.user.email}}</div>
</div>
<div mat-dialog-actions>
<button mat-button mat-dialog-close="view-profile" cdkFocusInitial>View profile</button>
<button mat-button mat-dialog-close="sign-out">Sign out</button>
</div>