function called twice inside angularjs controller

2019-01-22 03:33发布

问题:

I am new to angular js and currently stuck with very wired kind of a bug. function in a controllers runs twice when its called by view loaded against a route.

http://jsfiddle.net/4gwG3/5/

you will see alert twice!!

my view is simple

and my app code is following

var IB = angular.module('IB', []);    

//channel controller
IB.controller('channelsController', function ($scope, $routeParams) {
    $scope.greet = function () {
        alert('hi');
    };
});


IB.config(function ($routeProvider) {
    $routeProvider
    .when('/channels', {
        controller: 'channelsController',
        template: '{{greet()}}'
    })

    .otherwise({ redirectTo: '/channels' });

});

回答1:

First check that you're not initializing your Angular app twice (by having it initialized automatically with ng-app).

One time I had 2 html pages with ng-app (one for login.html and another for main.html) and this was a problem I realized later.

Second and for me the most important, check if you have attached your controller to multiple elements. This is a common case if you are using routing.

In my case I was navigating to DashboardController like so:

app.config(function($routeProvider){
    $routeProvider
    .when('/', {
        controller: 'DashboardController',
        templateUrl: 'pages/dashboard.html'
    })
});

But I also had this in dashboard.html:

<section class="content" ng-controller="DashboardController">

Which was instructing AngularJS to digest my controller twice.

To solve it you have two ways:

removing ng-controller from your html file like this:

<section class="content">

or removing controller from routing (that is normally situated in app.js):

app.config(function($routeProvider){
$routeProvider
        .when('/', {
            templateUrl: 'pages/dashboard.html'
        })
    });


回答2:

I think by creating an interpolation {{greet()}}, you create a watch on function greet. This function can get call as many time as digest cycle runs, so it is not a question about it running 1 or 2 times. So you should not depend upon the times the function is called.



回答3:

I dont know what you are trying to achieve here. There are two alerts 1. When the controller is called. 2. When the template is get evaluated.

template is to provide the view part, however, in this case template is just evaluating function which is not creating any view.



回答4:

I had the same problem, so I did:

$scope.init=function()
{
    if ($rootScope.shopInit==true) return;
    $rootScope.shopInit=true;
    ...
}
$scope.init();

Like if it were a singleton ! (I had many ajax calls each time I display, it was boring)