【问题标题】:UI Router RedirectTo after Promise from ResolveFn来自 ResolveFn 的承诺后的 UI 路由器 RedirectTo
【发布时间】:2019-01-14 20:17:47
【问题描述】:

我正在使用Angular 2+ (targeting Angular 5) version of UI Router,但如果有人有使用 Angular 1 版本的相同问题的资源,我会很高兴看到 - 但我知道 redirectTo 属性不是早期的原始功能UI Router 的版本。

我有一个父组件,它的模板有“标签”,每个标签都命名为<ui-view>s。

父组件模板:

<ui-view name="child1" *ngIf="isCurrentView()"></ui-view>
<ui-view name="child2" *ngIf="isCurrentView()"></ui-view>
...

这样,您可以看到父模板中除了这些“选项卡”之外什么都没有。所以我希望名为“child1”的ui-view 成为默认视图,并且我希望它从父视图一直处于活动状态,直到用户导航到不同的路线以打开另一个 ui 视图。

假设isCurrentView() 函数有效,并为应该可见的任何视图返回一个布尔值。一次应该只有一个视图可见。为了清楚起见,我包含此信息。

以这种方式设置状态。您注意到在 parentComponent 状态中有多个resolveFn。这些都调用 API 并且是异步的,在这些完成之前我们无法导航到任何“选项卡”。这种设置确保了这种情况。 child1 和 child2 组件都依赖于这些响应。

{
    name: "parentComponent",
    url: "/parent",
    component: ParentComponent,
    resolve: [
        {
            token: "apiDetail1",
            deps: [MyAPIService],
            resolveFn: (myAPIService) => { return myAPIService.getApiDetail1(); }
        },
        {
            token: "apiDetail2",
            deps: [MyAPIService],
            resolveFn: (myAPIService) => { return myAPIService.getApiDetail2(); }
        }
    ]
},
{
    name: "parentComponent.child1",
    url: "/child1",
    views: {
        child1: { component: Child1Component }
    }
},
{
    name: "parentComponent.child2",
    url: "/child2",
    views: {
        child2: { component: Child2Component } 
    }
}

我想在所有解析功能完成后立即重新路由到名为 parentComponent.child1 的状态 - 否则将无法获得必要的数据。但我不知道该怎么做。

我知道 UI 路由器有一个“redirectTo”属性,然后我可以在我的目标状态中传递它,如下所示:

redirectTo: "parentComponent.child1"

但是,redirectTo 在路由激活开始时完成。我知道我可以传入一个异步服务并让重定向等待该异步服务完成——但我不确定如何使用实际上在同一路由中等待解析功能的服务。

我已经调用了一次这些 API,所以我不需要再次调用它们。我只想在重定向之前等待已经被调用的那两个。但是怎么做呢?

【问题讨论】:

    标签: javascript angular routes angular-ui-router state


    【解决方案1】:

    在移动了一些不同的东西之后,我找到了一个的答案。这可行,但仍会产生我尚未诊断的控制台错误。如果有人可以提供更多见解或更深入的答案,我将不胜感激。

    我最终做的第一件事就是删除我所有的多个&lt;ui-view&gt; 标签。我只在父组件模板中留下了一个未命名的标签。只有一个,我也不需要神秘的isCurrentView()函数。

    父组件模板

    <ui-view></ui-view>
    

    国家

    然后,在我的状态下,我以这种方式定义了 redirectTo 函数:

    {
        name: "parentComponent",
        url: "/parent",
        component: ParentComponent,
        resolve: [
            {
                token: "apiDetail1",
                deps: [MyAPIService],
                resolveFn: (myAPIService) => { return myAPIService.getApiDetail1(); }
            },
            {
                token: "apiDetail2",
                deps: [MyAPIService],
                resolveFn: (myAPIService) => { return myAPIService.getApiDetail2(); }
            }
        ],
        redirectTo: (transitionService: Transition) => { // This service is of type Transition, the same object you would grab parameters from
            const apiCall1Promise = transitionService.injector().getAsync("apiDetail1"); 
            const apiCall2Promise = transitionService.injector().getAsync("apiDetail2");
            // I getAsync the same tokens I defined in my resolve functions
            return Promise.all([apiCall1Promise, apiCall2Promise]).then(()=>{
                // I don't need any of the results of the promises, since I already grab the information I need in the resolve functions, so I don't worry about getting the response here.
                return "parentComponent.child1"; // Since I need to wait for both calls, I use Promise.all instead of calling the promises directly.
            }).catch(() => {
                return "parentComponent.child1"; // This is likely bad form, but I want it to always redirect to this state, since I do not have anything else to show the user on the current parentComponent state.
            });
        }
    },
    {
        name: "parentComponent.child1",
        url: "/child1",
        component: Child1Component // since I'm not using named ui-view tags, I moved info out of the views property into the component property
    },
    {
        name: "parentComponent.child2",
        url: "/child2",
        component: Child2Component 
    }        
    

    }

    通过使用 getAsync() 将令牌绑定到 transitionService.injector(),然后重定向将等待 promise 返回。我等待我的两个解析(由它们的标记引用),一旦完成,我返回我希望它导航到的路线。

    但是,以这种方式完成后,我仍然收到此错误:

    Transition Rejection($id: 5 type: 2, message: The transition has been superseded by a different transition, detail: Transition#7( 'routeImNavigatingFrom'{} -> 'parentComponent.child1'{} ))
    

    我不清楚这个错误是什么意思,或者我为什么会收到它,因为我已经遵循了 redirectTo 文档。 There is an ongoing discussion on the error message here.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-16
      • 2017-01-18
      • 1970-01-01
      • 2016-11-10
      • 1970-01-01
      • 2015-05-17
      • 2017-01-28
      • 1970-01-01
      相关资源
      最近更新 更多