从效果关闭对话框组件

时间:2019-11-14 06:16:05

标签: angular angular-material ngrx-store ngrx-effects

我需要从@ ngrx / effect关闭角材料对话框

这是我的代码

import { MatDialogRef, MatDialog } from "@angular/material/dialog";
import { AddComponent } from "./../../add/add.component";

@Injectable()
export class UserEffects {
@Effect()
addNewUser$ = this.actions$.pipe(
    ofType(actions.UserActionTypes.addNewUser),
         mergeMap((user: actions.addNewUser) =>
             this.userService.createUser(user.user).pipe(
                map(() => {
                  new actions.LoadUsers(),
                  this.notificationService.success("User added successfully!");
                  this.dialogRef.close();     <------ // here i try to close
                }),
              catchError(error => of(new actions.Error(error.error)))
            )
        )
    );

constructor(
    private actions$: Actions<actions.UserActions>,
    private userService: UserService,
    private notificationService: NotificationPopUpServiceService,
    public dialogRef: MatDialogRef<AddComponent>
) {}
}

与此有关,我得到了错误

  

main.ts:13 NullInjectorError:R3InjectorError [EffectsRootModule-> InjectionToken ngrx / effects:根效果-> UserEffects-> MatDialogRef-> MatDialogRef-> MatDialogRef]:     NullInjectorError:没有MatDialogRef的提供程序!

从效果或服务上关闭材料对话的最佳方法是什么?因为我们总是需要为对话框组件设置一个名称?

谢谢

5 个答案:

答案 0 :(得分:3)

我认为关闭对话框的最佳解决方案是订阅effect变量 即

// close the dialog
// Inside the dialog component
 this.userEffects.addNewUser$.pipe(
     ofType(Actions.LoadUsers)
 ).subscribe(_ => this.matDialogRef.close());

答案 1 :(得分:1)

关于您的“发送了无效操作:未定义”

每个效果都必须调度一个动作,除非您指定: {dispatch:false}

答案 2 :(得分:0)

@Effect的构造函数中,您需要提供依赖项:

 private dialogRef: MatDialogRef<MyDialogComponentToClose>

您需要将MatDialogModule导入效果所在的模块中。

答案 3 :(得分:0)

我想我找到了解决方案,但是如果有更好的方法,请告诉我... 我添加this.dialogRef.closeAll()

@Effect()
    addNewUser$ = this.actions$.pipe(
     ofType(actions.UserActionTypes.addNewUser),
        mergeMap((user: actions.addNewUser) =>
          this.userService.createUser(user.user).pipe(
             map(() => {
               new actions.LoadUsers(),
               this.notificationService.success("User added successfully!");
               this.dialogRef.closeAll();    <--- //this is the key
             }),
    catchError(error => of(new actions.Error(error.error)))
  )
)

);

编辑:

模式已关闭,但出现错误

  

core.js:6014错误错误:效果“ UserEffects.addNewUser $”调度了无效操作:未定义

     

TypeError:操作必须是对象

有帮助吗? thnx

答案 4 :(得分:0)

您可以在对话框组件中收听actions$: Actions,对其进行订阅并在触发操作时关闭对话框,而无需重复使用NgRx效果并且无需注入所有对话框引用。

您的对话框组件的构造函数将包括:

constructor(    
    public dialogRef: MatDialogRef<YourDialogComponent>,
    private readonly actions$: Actions) {}

ngOnInit中,您将收听旨在关闭对话框的相关操作。我通常依靠ngOnDestroy取消订阅可观察对象。

private readonly subscription = new Subscription();

ngOnInit(): void {
    this.subscription.add(
      this.actions$
        .pipe(ofType(actions.UserActionTypes.LoadUsers))
        .subscribe(() => this.dialogRef.close())
    );
}

ngOnDestroy(): void {
    this.subscription.unsubscribe();
}

请注意您正在听的动作;它必须是由addNewUser$效应触发的,在您的情况下似乎是new actions.LoadUsers()。常见的模式是在addNewUseraddNewUserSuccess之后执行addNewUserFailure操作。

您可能同时弹出几个错误对话框。这种方法允许管理由不同组件组成的并发对话框:closeAll()将(不出意外地)关闭所有实质性对话框。