【问题标题】:Open dialog when changing page from menu in Angular 4从Angular 4中的菜单更改页面时打开对话框
【发布时间】:2017-11-02 14:47:14
【问题描述】:

我有一个 Angular 4 应用程序。在一个页面(editionPage)上,我想在离开页面之前打开一个对话框来确认是否保存。

所以,我有一个按钮可以转到上一页。当我单击此按钮时,我会打开对话框。

但我也想在单击侧边栏菜单中的按钮时打开对话框。

这是我的侧边栏菜单:

<nav class="sidebar" [ngClass]="{sidebarPushRight: isActive}">
<ul class="list-group">
    <a routerLink="/first" [routerLinkActive]="['router-link-active']" class="list-group-item">
        <div class="titleMenu first" >{{ 'first' | translate }}</div>
    </a>
    <a routerLink="/tests" [routerLinkActive]="['router-link-active']" class="list-group-item">
        <div class="titleMenu">{{ 'Tests' | translate }}</div>
    </a>
</ul>
</nav>

然后我像这样打开我的模态对话框:

this.bsModalRef = this.modalService.show(DialogSaveEditComponent);

我尝试使用带有CanDeactivate 的守卫,但它并没有像我想要的那样工作,因为我可以在对话框打开后返回正确的布尔值,所以在后台页面更改之前选择选项或背景永远不会改变。

你知道我该怎么做吗?

编辑 现在我调用一个函数,当我单击菜单中的按钮时会打开一个对话框。但是由于routerLink="/first" [routerLinkActive]="['router-link-active']" 页面发生了变化,然后出现了对话框。单击对话框中的按钮后如何更改页面或取消更改页面?

【问题讨论】:

    标签: angular typescript dialog modal-dialog


    【解决方案1】:

    你可以这样做 当您的导航从

    结束时,赶上导航结束
    this.router.events.subscribe(
            res => {
                if(res instanceof NavigationEnd && res.url.startsWith('YOUR URL')) {
                   //SHOW YOUR MODAL
                } 
            }
        )
    

    【讨论】:

    • 这不起作用,因为 url 是最终 url 而不是开始 url。
    • "所以,我有一个按钮可以转到上一页。当我点击这个按钮时,我打开了对话框。" => 所以这不是同一页吗?
    • 否则您只需让结果 url 打开对话框,您也可以从该视图的父级执行此操作
    • 对话框打开一个编辑页面。所有的动作都从这个页面开始。我也想在单击侧边栏菜单中的按钮时打开对话框。我想在更改页面之前显示对话框。当我们在对话框中选择一个选项时,页面是否需要更改。
    • 所以你是对的,使用警卫来防止导航
    【解决方案2】:

    所以,我通过使用守卫来阻止用户更改页面,成功了我想做的事情。

    这是新的守卫:

    @Injectable()
    export class SaveEditGuard implements CanDeactivate<ConfirmDialogSaveBatch> {
        sub: Subscription;
        result: boolean;
    
    constructor(private router: Router, private confirmDialogService: ConfirmDialogSaveBatchService, private datasService: DatasService) {
    
    }
    
    canDeactivate(component: ConfirmDialogSaveBatch, currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot,
                  nextState?: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    
        if(!this.datasService.clickOnSaveButton){
            this.confirmDialogService.confirm();
        }
    
        return this.datasService.returnSaveEditValue$;
    }
    }
    

    所以,如果用户点击保存按钮,我不想显示对话框。所以,当我点击保存按钮时,我将this.datasService.clickOnSaveButton设置为true,将returnSaveEditValue设置为true,这样我们就可以退出页面了。

    如果用户通过单击菜单退出页面,则对话框将打开并等待响应,因为ReplaySubject&lt;boolean&gt;

    这是服务中的代码:

    public returnSaveEditValue = new ReplaySubject<boolean>(1);
    public clickOnSaveButton: boolean = false;
    
    
    public notifyRefreshDatas(data: any) {
        if (data) {
            this.subject.next(data);
        }
    }
    
    setReturnSaveEditValue(val: boolean){
        this.returnSaveEditValue.next(val);
    }
    
    get returnSaveEditValue$() {
        return this.returnSaveEditValue.asObservable();
    }
    

    如果用户点击保存,我使用前面的函数将 observable 变量设置为 true:this.datasService.setReturnSaveEditValue(true); 当用户进入页面或显示新对话框时,我重新初始化ReplaySubjectthis.datasService.returnSaveEditValue = new ReplaySubject&lt;boolean&gt;(1);,所以如果用户点击取消并想再次退出页面,可观察变量再次未初始化,所以te app 等待对话框的响应。

    为了从任何地方调用对话框,我为对话框创建了一个服务。在这个服务中,我有一个调用并打开对话框的函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多