starcorn
starcorn

Reputation: 8531

AngularJS: Function in controller is called three times

I have a controller which calls a save service, and it is for some reason triggered three times. It is not that great if it saves three instances every time it is triggered. Is my approach of solving it wrong?

I found this following article which says it is a normal behavior in AngularJS

Below is an example which triggers that behavior. I'm using webpack to bundle AngularJS, and other dependencies.

FooCtrl

import {IFooService} from "./FooService";

export class FooCtrl {

    static $inject = ["FooService"];

    public fooService: IFooService;

    constructor(fooService: IFooService) {
        console.log("creating foo controller");
        this.fooService = fooService;
    }

    public callService(): boolean {
        console.log("call service");
        this.fooService.save();
        console.log(this.fooService.getSaves());
        return true;
    }
}

FooService

export interface IFooService {
    save(): void;
    getSaves(): number;
}

export class FooService implements IFooService{

    private saves: number = 0;

    public save(): void {
        console.log("saved");
        this.saves++;
    }

    public getSaves(): number {
        return this.saves;
    }
}

Main

namespace Main {

    let fooModule = new FooModule.Module();

    let main = angular.module("myApp", [
        "ngRoute",
        fooModule.getFooModule(),
    ]);

    main.controller("BarCtrl", function($scope) {
        $scope.message = "Bar";
    });

    main.config(function($routeProvider: ng.route.IRouteProvider) {
        $routeProvider.when("/", {
            "templateUrl": "foo/index.html",
        });
    });
}

index.html

<!doctype html>
<html ng-app="myApp">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="http://localhost:8080/webpack-dev-server.js"></script>
    <script src="vendors.bundle.js"></script>
    <script src="app.bundle.js"></script>
</head>
<body>
    <div ng-view></div>
</body>
</html>

index.part.html

<div ng-controller="FooCtrl as ctrl">
    <p ng-bind="ctrl.callService()"></p>

</div>

Upvotes: 0

Views: 49

Answers (1)

David Bohunek
David Bohunek

Reputation: 3201

Because you are binding your method to the <p> element, it will be trigger on every digest cycle so that angular can check if the value changed.

I am not sure what you are trying to do exactly, but it looks like this this method should be trigger by a user action or maybe periodically and controlled using $timeout service.

Read more about scope digest cycle in the official documentation.

Upvotes: 1

Related Questions