【问题标题】:Angular routing and state handling problems角度路由和状态处理问题
【发布时间】:2015-02-12 00:32:09
【问题描述】:

我有 3 个嵌套状态:

$stateProvider
        .state('A', {                    
            url: '/a',
            templateProvider: function ($templateCache) {

                return $templateCache.get('pages/a.html');
            },
            controller: 'aController'
        })

        .state('A.B', {
            url: '/b',
            templateProvider: function ($templateCache) {

                return $templateCache.get('pages/b.html');
            }
            controller: 'bController'
        })

        .state('A.B.C', {
            url: '/c',                    
            templateProvider: function ($templateCache) {

                return $templateCache.get('pages/c.html');
            },
            controller: 'cController'
        })

假设 A 是应用的初始状态。现在,当在状态 A 中单击指向状态 B 的链接时,会调用 $state.go('.B', ...) ,状态 B 必须从 A 获取参数,以便它可以使用该参数调用某些服务并渲染数据。

同样,当在状态 B 上点击指向状态 C 的链接时,C 必须从 B 获取参数,这样它才能正常工作并正确显示数据。

第一个问题:

将这些参数向下传递的最佳方式是什么?嵌套控制器以使父范围在子范围中可见是错误的吗?还是应该将它们作为参数传递?

第二个问题(取决于第一个问题的答案):

html模板应该如何构造(特别是关于'ui-view'指令),所以当浏览器返回按钮在来自B之后点击状态C时,模板B的控制器不会被触发,所以状态 B 显示与进入状态 C 之前相同的数据而无需重新加载。从 A 回到状态 B 后点击返回也是如此。

第三个问题:

如果用户进行了以下转换:A->B->C,然后导航到某个不相关的状态 D(例如通过单击主菜单上的链接),然后在状态 D 中按下返回按钮,如何防止控制器 C 因没有输入参数而分崩离析?

第四题(与第三题有关):

前提: 到达状态 B 的唯一“正确”方法是点击状态 A,同样要到达 C,用户必须先通过 A->B。

那么,当用户从某个不相关的状态 D 手动输入例如 URL B 时,我该如何处理?同样,一切都崩溃了,因为 B 没有输入参数。

谢谢。

【问题讨论】:

    标签: angularjs nested angular-ui-router state


    【解决方案1】:

    第 1、3、4 个问题可以通过使用您所在州的 url 上的参数来解决。例如,状态 A.B 的 URL 可以是 /b?x&y&z 而不仅仅是 /b。然后要从 A 过渡到 A.B,您将使用:

    $state.go('A.B', {x: "val1", y: "val2", z: "val3"});
    

    这解决了第一个问题,因为您将参数从 A 传递到 B。这解决了第三个问题,因为状态 A.B.C 在从另一个状态返回后不会崩溃,因为 URL 历史记录包含参数。并且很明显这种方法将如何解决用户直接在地址栏中输入 URL 的第四个问题。

    问题 2 提出了一个稍微难以解决的问题。但是您可以做的是在 A 和 B 之间引入一个中间状态,其唯一目的是防止按下后退按钮时重新加载状态 A 的控制器。

    .state('A', {
                abstract: true,                    
                url: '/a',
                templateProvider: function ($templateCache) {
    
                    return $templateCache.get('pages/a.html');
                },
                controller: 'aController'
            })
    .state('A.int', {
    
                url: '/a/view',
                template: <div></div>,
                controller: 'aIntermediateController'
            })
            .state('A.int.B', {
                url: '/b',
                templateProvider: function ($templateCache) {
    
                    return $templateCache.get('pages/b.html');
                }
                controller: 'bController'
            })
    

    注意,我将状态 A abstract 设为您无法直接导航到它。相反,您直接导航到 A.int。当您最初加载状态 A.int 时,aController 将在 aIntermediateController 执行之前执行一次。随后,对 A.int 的任何状态更改都只会执行一个IntermediateController。这就是您可以防止 aController 多次运行的方法。 同样,您可以以相同的方式在状态 B 和 C 之间添加中间视图。

    【讨论】:

    • 感谢您的洞察力,其中一些可能会有所帮助。
    • 你好。在玩了一会儿之后,我有一个后续问题:如果我不能/不想使用 url 参数,但状态定义的 params 属性怎么办?在这种情况下,我会丢失后退按钮上的参数。我可以为特定状态实现某种参数缓存,我可能会,但如果你知道更好的方法,请分享。谢谢。
    • 基本上,您试图记住页面的状态并在导航到该页面时调用该状态,无论是通过另一个页面还是直接通过地址栏。从页面导航到页面时调用状态很容易,因为您可以提供一些输入来构建状态。但是,如果您不使用 URL 参数,当用户通过地址栏导航到页面时,您将如何提供输入来构造状态?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 2014-06-22
    • 2019-07-08
    • 2020-01-18
    • 1970-01-01
    • 1970-01-01
    • 2014-02-18
    相关资源
    最近更新 更多