简体   繁体   English

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

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

I am injecting HTML with a ui-view into the DOM, then changing state using ui.router. 我将带有ui视图的HTML注入DOM,然后使用ui.router更改状态。 Everytime the state is changed, that controller seems to be registered an additional time, thus the code in the controller executes multiple times. 每次状态更改时,该控制器似乎都会被注册一次,因此控制器中的代码将多次执行。 You can see a demonstration of this with the plnkr below. 您可以在下面的plnkr中看到此演示。 (just pop open the console, then click back and forth between the left and right button and notice that the controllers execute an additional time for each click.) (只需弹出打开控制台,然后在左右按钮之间来回单击,请注意,控制器每次单击都会花费额外的时间。)

If the ui-views live on the index.html as static content then life is good, and the issue does not happen. 如果ui视图作为静态内容存在于index.html上,则说明生活良好,并且不会发生此问题。 It is only when injecting them into the DOM. 仅当将它们注入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",
                }
            }
        });

    }
]);

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

You are amost there. 你在那儿。 And I am not challenging or judging this approach, just providing the answer. 我并没有挑战或判断这种方法,只是提供了答案。 There is a working example . 一个可行的例子

You've properly created new scope. 您已经正确创建了新范围。 Very good. 很好。 But that is just an A . 但这只是一个A。 The essential and curcial B is missing. 基本的和重要的B丢失了。 B - is opposite to A === destroy new scope (once old) . B-A相反= ===销毁新范围(一旦旧)

This will do the job for us: 这将为我们完成工作:

 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);

        };
    }
]);

Check that all in action here 在这里检查所有动作

Why do you make it so complicated? 你为什么要这么复杂? Is there a special reason why you are using 是否有特殊原因使您使用

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);

Isn't it possible to use something like 不可能使用类似的东西

<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>

I used ui-sref to easily navigate between states. 我使用ui-sref轻松在状态之间导航。 I have prepared a little demo to illustrate that. 我准备了一个小演示来说明这一点。 Have a look here . 在这里看看。 Does that help? 有帮助吗? Is it usable? 可以使用吗? That way you don't even need the menuController. 这样,您甚至不需要menuController。

If you need named views (multiple nested views) have a look at the documentation . 如果您需要命名视图(多个嵌套视图),请查看文档 Is is explained pretty well. 是很好解释的。 You would end up with something like: 您最终将得到以下结果:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM