首页 文章

如何在后台导航时调用ActivatedRoute.queryParams.subscribe?

提问于
浏览
1

How to stop ActivatedRoute.queryParams.subscribe to be called on back navigation?

platform(s) the issue occur on

  • iOS iOS 11 ipad mini2

  • iphone 6 plus,

  • Nativescript游乐场

the following version numbers

  • tns-core-moduels 4.2.0

  • tns-ios 4.2.0

  • angular / compiler-cli 6.1.2

  • angular / router 6.1.2

  • nativescripte-angular 6.1.0

the steps to reproduce it: 共有3页:主页,实体,联系方式 . 它们是根级页面并使用page-router-outlet

  • 在主页中,点击按钮,转到param id = 1的实体页面
this.routerExtensions.navigate(['/entity'],
        {
            queryParams: {
                id: '1'
            }
        }
    );
  • 在实体页面中,点击另一个按钮,转到param id = 2的联系页面
this.routerExtensions.navigate(['/contact'],
        {
            queryParams: {
                id: '2'
            }
        }
    );
  • 在联系页面中,点击左上角的系统后退按钮返回实体页面

expect result: 在实体页面中,不应在后退导航和显示实体页面上调用router.queryParams.subscribe而不进行任何刷新 .

export class EntityComponent implements OnInit {
...
ngOnInit(): void {

    //if it's from Home page, that's OK;  
    //but how to stop it to be called on navigating back? 
    this.router.queryParams.subscribe(params => {
    console.log("EntityComponent queryParams with id : " + params.id);

    //To refresh page on regular navigating using id = 1.  
    //On back navigation, the page shouldn't be refreshed.

        });
}

使用param id = 2(联系页面id)调用 actual result: this.router.queryParams.subscribe

code: https://play.nativescript.org/?template=play-ng&id=SgrzAJ&v=9


BTW,@ tsonevn建议在github中的解决方案不起作用,这一行:

this.router.queryParams.unsubscribe();

甚至在操场上编译问题 . this.router.queryParams没有'unsubscribe'方法 .

entity.component.ts

当您导航到另一个页面并在进入EntityComponent时再次订阅时,我建议您从this.router.queryParams取消订阅 . 例如:

onButtonTap(): void {
     this.router.queryParams.unsubscribe();
    console.log("Entity Button was pressed, go to contact Page with id = 2");
    this.routerExtensions.navigate(['/contact'],
        {
            queryParams: {
                id: '2'
            }
        }
    );
}

1 回答

  • 0

    OP解决方案 .

    感谢@tsonevn,他在github更新了他的解决方案,现在可以使用了 .

    新代码演示:https://play.nativescript.org/?template=play-ng&id=SgrzAJ&v=13

    基本上,这一行可以点击按钮离开页面 .

    this.subs.unsubscribe();
    

    但是,实际情况可能更复杂 . 例如:实体页面中有3个子组件,每个人都有一个导航到联系页面的按钮 . 我们需要将'this.subs'传递给子组件,并保持3个位置来做'unsubscribe()' .

    怎么在一个地方做?

    Router Guard' CanDeactivate '是一种注入它的好方法 .

    步骤:

    • 创建一个can-deactivate-guard.ts,在页面停用时调用'component.unsubscribeQueryParams'方法
    export class CanDeactivateGuard implements CanDeactivate<any> {
    canDeactivate(component: any, route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        if (component.unsubscribeQueryParams()) {
            return true;
        } else {
            return false;
        }
    }
    

    }

    • 把它放在'entity-routing.module.ts'中
    const routes: Routes = [
    { path: "entity", component: EntityComponent, canDeactivate: [CanDeactivateGuard] }];
    
    • 在'entity.component.ts'中实现方法'unsubscribeQueryParams'
    unsubscribeQueryParams() {
    if (this.subscription) {
        //be called by CanDeactivateGuard.canDeactivate() on leaving this page.
        this.subscription.unsubscribe();    
    }       
    return true; }
    
    • 将'can-deactivate-guard'注册到'app.module' .

    使用'CanDeactivate'的另一个原因是使用page-router-outlet,当前进时,将不会调用当前页面'ngOnDestroy'方法,因此将'.subscription.unsubscribe()放在'ngOnDestroy'中不起作用 .

    来自Nativescript文档:

    使用page-router-outlet向前导航时,当前页面和视图将保存在本机导航堆栈中 . 相应的组件不会被销毁 . 它是缓存的 .

    有关详细信息,请查看'component lifecycle when using page-router-outlet and router-outlet'

    此问题已得到解决 .

    相关链接:

相关问题