AngularJS:控制器在使用 UI 路由器更改状态时注册多次

AngularJS: Controllers registering multiple times when changing state with UI Router

我将 HTML 和 ui 视图注入 DOM,然后使用 ui.router 更改状态。每次状态更改时,该控制器似乎都会额外注册一次,因此控制器中的代码会执行多次。您可以在下面的 plnkr 中看到这方面的演示。 (只需弹出控制台,然后在左右按钮之间来回点击,注意每次点击控制器都会执行额外的时间。)

如果 ui-views 在 index.html 上作为静态内容存在,那么生活是美好的,问题就不会发生。仅当将它们注入 DOM.

var app = angular.module('app', ["ui.router", "appHome", "appOther"]).config([
             "$urlRouterProvider", "$stateProvider", "$locationProvider", 
    function ($urlRouterProvider,   $stateProvider,   $locationProvider) {

        $stateProvider.state('appHome', {
            url: '/home/index',
            views: {
                "Alerts": {
                    template: 'THINGS',
                    controller: "AlertsController as Alerts",
                }
            }
        }).state('appOther', {
            url: '/other/index',
            views: {
                "Other": {
                    template: 'THINGS',
                    controller: "OtherController as Other",
                }
            }
        });

    }
]);

Plunker 上的测试用例:http://plnkr.co/edit/M2wzVLSSgZ7naOi58qgL

你为什么搞得这么复杂?您使用

有什么特殊原因吗
if(view == 'Alerts'){
   view = '<div ui-view="Alerts"></div>';
   state  = 'appHome'
}
else{
   view = '<div ui-view="Other"></div>';
   state  = 'appOther'
   }

$('#test').html($compile(view)(scope));
$state.go(state);

难道不能使用类似

的东西吗
<div ng-controller="MenuController">
   <button ui-sref="appHome" value="CLick Me">GoTo Alerts</button>
   <button ui-sref="appOther" value="CLick Me">GoTo Other</button>
</div>
<section ui-view></section>

我使用 ui-sref 在状态之间轻松导航。我准备了一个小演示来说明这一点。看看here。 这有帮助吗?可以用吗?这样你甚至不需要 menuController。

如果您需要命名视图(多个嵌套视图),请查看 documentation。解释得很好。你最终会得到类似的东西:

<!-- index.html -->
<body>
  <div ui-view="alerts"></div>
  <div ui-view="other"></div>
</body>

$stateProvider
  .state('report', {
    views: {
      'alerts': { ... templates and/or controllers ... },
      'other': {},
    }
  })

你快到了。 而且我不是在挑战或判断这种方法,只是提供答案。a working example

您已正确创建新范围。非常好。但这只是一个A。缺少基本的和常用的 BB - 与 A 相反 === 销毁新作用域 (旧的).

这将为我们完成工作:

 app.controller('MenuController', ["$scope","$compile", "$state","$http",
    function MenuController($scope,$compile, $state, $http) {
        $scope.goToUrl = function (view) {

                // was scope previously created
                var hasPreviousChildScope = this.childScope !== void 0
                                         && this.childScope !== null;

                if(hasPreviousChildScope)
                {
                  // we must clear after ourselves
                  this.childScope.$destroy();
                  this.childScope = null;
                }

                // create new scope
                this.childScope = $scope.$new();

                var html;
                var state;
                if(view == 'Alerts'){
                  view = '<div ui-view="Alerts"></div>';
                  state  = 'appHome'
                }
                else{
                  view = '<div ui-view="Other"></div>';
                  state  = 'appOther'
                }
                $('#test').html($compile(view)(this.childScope));
                $state.go(state);

        };
    }
]);

检查所有 in action here