如何使用mat-dialog的backgroundClick来关闭对话框并将更改后的数据发送回父组件

时间:2019-01-28 18:33:30

标签: angular angular-material

我有以下情况: 我正在使用mat-dilog显示* ngFor卡的信息,该卡中有一些静态信息,例如消息正文,标题和发布者,但我也有一些动态元素,在这种情况下为“赞”按钮 当某人单击对话框外的“喜欢”按钮(该视图是出版物的展开图)时,“喜欢”按钮变为红色,并且其计数器收到它的值+ 1,如果该人再次单击该按钮,它将变成灰色并具有值其中-1。 如果有人打开对话框并单击按钮,然后单击关闭按钮,则效果很好,但是如果有人单击“喜欢”按钮,然后单击背景或按“ esc”,则数据不会发送回父组件。我的代码如下:

visualize(value: any) { //method that opens the dialog

    if (value.link && !value.video_destaque)
        window.open(value.link, "_blank");
    else {
        const publicationData = { //pass the data to dialog
            id: value.id,
            cabecalho: value.header,
            corpo: value.body,
            ...
            curtiu: value.curtiu,
            classeFavorite: value.classeFavorite,
            num_curtidas: value.num_curtidas,
        };

        const dialogRef = this.dialog.open(VisualizePublicationComponent, { //open dialog
            maxHeight: '85vh',
            width: '70vh',
            panelClass: 'custom-dialog-container',
            disableClose: true,
            data: {
                publicacao: publicationData
            }
        });

        dialogRef.afterClosed().subscribe(result => { 
            this.post.curtiu = result.curtiu;
            this.post.favoritou = result.favoritou;
            this.post.num_curtidas = result.num_curtidas;
            this.post.classeLike = result.classeLike;
            this.post.classeFavorite = result.classeFavorite;
        });
    }
}

最后一部分“ dialogRef.afterClosed ...”将数据传递回父组件,但仅与mat-dialog-close按钮一起使用,似乎如果您在对话框外部单击,则认为您想要取消并完全忘记数据。

因为它是一个喜欢的按钮,用户可能想要阅读该帖子,然后喜欢它并以最简单的方式关闭它(在框外单击)。

我认为我的问题的答案与以下代码有关

dialogRef.backdropClick().subscribe(() => { dialogRef.close(); })

但是我不知道我缺少什么。

3 个答案:

答案 0 :(得分:1)

尝试添加此

VisualizePublicationComponent

...
constructor(public dialogRef: MatDialogRef<VisualizePublicationComponent>) {  }
...

ngOnInit() {
   this.dialogRef.beforeClose().subscribe(() => this.dialogRef.close(this.resultData));
}
...

this.resultData 是要返回到父组件的数据。我已经尝试过了,它适用于ESC和背景幕点击。 希望有帮助。

答案 1 :(得分:0)

就材料设计而言,在对话框外单击与按Escape键相同,并且两者都等同于取消操作,因此不应发生数据更改。如果用户取消更改,他们不会期望更改被“推送”。

话虽如此,如果您要访问对话框的数据副本(而不是适当的“关闭”的“结果”),则可以使用dialogRef.componentInstance.data

dialogRef.afterClosed().subscribe(result => { 

    if (!result) {
        result = dialogRef.componentInstance.data;
    }

    this.post.curtiu = result.curtiu;
    this.post.favoritou = result.favoritou;
    this.post.num_curtidas = result.num_curtidas;
    this.post.classeLike = result.classeLike;
    this.post.classeFavorite = result.classeFavorite;
});

答案 2 :(得分:0)

答案与我期望的略有不同,我的同事帮助了我,我已经有了一个功能,可以控制“赞”按钮,它可以改变按钮的颜色,并在计数器上加1等等,我需要在同一函数中调用服务中的方法,该方法将发出http请求以更改所有内容,现在在模型中创建了like按钮背后的逻辑,因此当http请求查找数据返回一个已经返回正确输出的模型,这种方法更好,因为它可以立即更新对话框和父组件的视图。

我仍然相信,有一种方法可以对垫对讲机先行者做同样的事情,但这并不是必须的。

这是我提到的功能:

public likeControl(publicacao: Publicacao) {
    const resultadoCurtir = publicacao.curtir();

    if (resultadoCurtir) {
        this.consumerCommunicationService.likePost(this.pessoa, publicacao.id).subscribe(
            response => {
                if (response.status < 299) {
                    PostCardComponent.successMessageToast('Pronto!');
                } else {
                    const promise = PostCardComponent.errorMessageFromResponse(response);
                }
            }
        );
    } else {
        this.consumerCommunicationService.dislikePost(this.pessoa, publicacao.id).subscribe(
            response => {
                if (response.status < 299) {
                    PostCardComponent.successMessageToast('Pronto!');
                } else {
                    const promise = PostCardComponent.errorMessageFromResponse(response);
                }
            }
        );
    }
}

这是服务方法的示例:

public likePost(consumerId, postId): any {
    return this.http.put(environment.baseUrl + '/consumidor/' + consumerId + '/mensagens/mensagem/' + postId + '/curtir', {},
        {observe: 'response'})
        .pipe(
            tap((response: any) => console.debug(JSON.stringify(response))),
            catchError(this.handleError('likePost(' + consumerId + ', ' + postId + ')', []))
        );

}

这是不完整的,那里仍然有很多功能,但这是主要思想,这样我的代码可以比我的意图更好地工作,并保持良好的做法并遵循我们正在实现的体系结构,谢谢为您的答案。