Angular 如何使用mat对话框的backdropClick关闭对话框并将更改的数据发送回父组件

Angular 如何使用mat对话框的backdropClick关闭对话框并将更改的数据发送回父组件,angular,angular-material,Angular,Angular Material,我有以下情况: 我使用mat dilog来显示*ngFor卡的信息,在这张卡中有一些静态信息,比如消息主体、标题和发布者,但我也有dinamic元素,在本例中是一个类似的按钮。 当有人单击对话框外的like按钮(这是出版物的展开视图)时,like按钮变为红色,其计数器接收到的值为+1,如果该人再次单击该按钮,则该按钮变为灰色,其de值为-1。 如果有人打开对话框并单击按钮,然后单击“关闭”按钮,则效果良好,但如果有人单击“相似”按钮,然后单击背景或按“esc”,则数据不会发送回父组件。我的代码如

我有以下情况: 我使用mat dilog来显示*ngFor卡的信息,在这张卡中有一些静态信息,比如消息主体、标题和发布者,但我也有dinamic元素,在本例中是一个类似的按钮。 当有人单击对话框外的like按钮(这是出版物的展开视图)时,like按钮变为红色,其计数器接收到的值为+1,如果该人再次单击该按钮,则该按钮变为灰色,其de值为-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按钮一起工作,如果您在对话框外单击,它似乎认为您希望取消并完全忘记数据

由于它是一个like按钮,用户可能希望阅读文章,然后喜欢它并以最简单的方式将其关闭(单击框外)

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

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

但我不知道我遗漏了什么。

试着补充一下

可视化发布组件
。。。
构造函数(public dialogRef:MatDialogRef){}
...
恩戈尼尼特(){
this.dialogRef.beforeClose().subscribe(()=>this.dialogRef.close(this.resultData));
}
...
其中this.resultData是要返回到父组件的数据。我已经试过了,它适用于esc和背景单击。
希望对您有所帮助。

就材料设计而言,在对话框外单击与按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;
});

答案与我预期的有点不同,我的同事帮我解决了这个问题,我已经有了一个功能,可以控制like按钮,它改变了按钮的颜色,并在计数器上添加了1个,等等。,我需要在同一个函数中调用服务中的一个方法,该方法将发出http请求来更改所有内容,like按钮后面的逻辑现在在模型中生成,因此当http请求查找数据时,它将返回一个已经返回正确输出的模型,此方法更好,因为它会立即更新对话框和父零部件的视图

我仍然相信有一种方法可以对mat dialog的所有者做同样的事情,但这并不是真的必要

下面是我提到的函数:

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);
                }
            }
        );
    }
}

这是不完整的,这里有很多函数,但这是主要的思想,这样我的代码比我实际想要的更好,我保持良好的实践,并遵循我们正在实现的架构,谢谢您的回答。

不清楚对话框中如何使用
likeControl
likePost
函数。由于这是您问题的答案,读者可能会发现了解这些函数如何解决您的问题很有用。当“一切”已经是本地的时,不必发出“更改一切”的请求。likeControl是一个函数,单击like按钮时调用它,likePost是服务内部的一个函数,用于与后端通信,所有东西都不是本地的,该信息保存在外部数据库中。我们还需要取消订阅吗?
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 + ')', []))
        );

}