如何使用ui-router手动实例化控制器?

时间:2015-01-29 19:39:47

标签: angularjs angular-ui-router

所以,在我的“根”控制器......

$scope.subElements = [
            { heading: "Contact", state: "institution.contact", active: false },
            { heading: "Adapters", state: "institution.adapters", active: false },
            { heading: "Transactions", state: "institution.transactions", active: false },
            { heading: "Organizations", state: "institution.organizations", active: false },
            { heading: "Users", state: "institution.users", active: false }
        ];

并在我的“根”视图中......

<tabset>
        <tab ng-repeat="elem in subElements"
             heading="{{elem.heading}}"
             select="go(elem.state)"
             active="elem.active">
        </tab>
    </tabset>

它运行良好,但问题是,在用户单击选项卡标题之前,控制器不会被实例化。因此,用户必须等待从远程端点加载控制器所需的数据。我更希望对数据加载进行更细粒度的控制,例如触发其他子控制器在后台加载并在完成后激活各自的选项卡。

我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:0)

您是否尝试过使用州的解决方案对象?来自文档:

  

您可以使用resolve为控制器提供自定义状态的内容或数据。 resolve是一个可选的依赖关系图,应该注入控制器。

     

如果这些依赖项中的任何一个是promise,它们将在实例化控制器并触发$ stateChangeSuccess事件之前被解析并转换为值。

https://github.com/angular-ui/ui-router/wiki#resolve

例如:

$stateProvider.state('institution.transactions', {
    'url': '/institution/transactions',
    'controller': 'transactionsController',
    'templateUrl': 'transactions.html',
    'resolve': {
        'transactions': [
          'TransactionService',
          function (TransactionService) {
              return TransactionService.get();
          }
        ]
    }
});

您现在可以将交易注入您的控制器:

angular.module('app').controller('transactionsController', [
    '$scope',
    'transactions',
    function ($scope, transactions) {
        $scope.transactions = transactions;
    }
]);

现在,当更改为状态institution.transactions时,控制器将等待初始化,直到服务返回的承诺得到解决。只有这样控制器才会启动并切换视图。同时,您可以使用onStateChangeStartonStateChangeSuccess事件来显示某种进度/忙碌指标。请参阅:https://github.com/angular-ui/ui-router/wiki#state-change-events

您还可以在父状态中解析所有子状态依赖关系,只需将它们全部放入该状态的解析对象中即可。它们将提供给孩子们:

$stateProvider.state('institution', {
    'url': '/institution',
    'controller': 'institionController',
    'templateUrl': 'institution.html',
    'resolve': {
        'contact': [
          'ContactService',
          function (ContactService) {
              return ContactService.get();
          }
        ]
        'adapters': [
          'AdapterService',
          function (AdapterService) {
              return AdapterService.get();
          }
        ]
        'transactions': [
          'TransactionService',
          function (TransactionService) {
              return TransactionService.get();
          }
        ],
        // and on and on and on
    }
});