角度路由和状态处理问题

时间:2015-02-11 14:25:20

标签: angularjs nested angular-ui-router state

我有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模板(特别是关于&u-view'指令),所以当从B来源单击状态C时,浏览器后退按钮,模板B的控制器没有被触发,因此状态B显示与转到状态C之前相同的数据而不重新加载。从A开始点击状态B也是如此。

第三个问题:

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

第四个问题(与第三个问题相关):

前提:唯一的'权利'到达状态B的方式是通过点击状态A,同样为了到达C,用户必须首先通过A-> B。

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

谢谢。

1 个答案:

答案 0 :(得分:0)

第一,第三和第四个问题可以通过使用州的网址上的参数来解决。例如,状态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 抽象,以便您无法直接导航到它。相反,您直接导航到A.int。当您最初加载状态A.int时,aController将在执行一个中间控制器之前执行一次。随后,对A.int的任何状态更改将仅执行aIntermediateController。这就是如何阻止aController多次运行的方法。 同样,您可以以相同的方式在状态B和C之间添加中间视图。