Search code examples
angularjsng-bindangular-controller

Angular controller load()


This is a trivia for many, but I never worked with angular before and I need help to achieve a simple task, cause I'm stucked.

My ng-controller processctrl has a load() method declared. My view has two calls to ng-controller="processoctrl", causing load() method to run twice. processctrl also has a property currentPhase that starts null and load() set its value. I could just write ($scope.currentPhase || load()) to prevent double load(), but the bind to currentPhase occurs atop (in DOM) of the repeater.

I could place an object property into the $rootScope and update it from processoctrl.scope.load(), but it would turn into a madness.

I could simply $($(".headerCurrentPhase")[0]).html($scope.currentPhase) into my load() method, but it's insanity too.

I could rewrite load() to getProcesses = function(){} and $rootScope.$emit('getProcesses',{}) elsewhere and into the controller $rootScope.$on('getProcesses',getProcesses) to prevent this double load(), but I think this is redundate, so how to simply call a controller function instead of load()? Or how to achieve this simple task? Use a directive?

view:

<div ng-include src="'includes/overview-header.html'"></div>
<div ng-include src="'includes/process-info.html'"></div>

excerpt of includes/overview-header.html :

<div class="col-md-12">
....
    <h4><strong>currentPhase</strong></h4>
    <p ng-controller="processoctrl">
       <span class="label label-primary headerCurrentPhase" ng-bind="currentPhase"></span>
    </p>
</div>

excerpt of includes/process-info.html :

<tbody ng-controller="processctrl">
    <tr ng-repeat="Process in Processes|orderBy:'ID'">
        <td>{{Process.isCurrent}}</td>
        <td>{{Process.isCurrent}}</td>
        <td>{{Process.ID}}</td>
        <td>{{Process.Title}}</a></td>
    </tr>
</tbody>

processoctrl

(function (app) {
   app.controller('processctrl', function ($scope, $rootScope, $routeParams, factorysvc) {
       $scope.Processes = [];
       $scope.currentPhase = null;
       load();

       //($scope.currentPhase || load())

       function load() {
            var promiseGet = factorysvc.getPsby($routeParams.itemId);

            promiseGet.then(function (data) {

                $scope.Processes  = data;

                $rootScope.root.empreendimento.currentPhase = $scope.currentPhase = data[0].currentPhase.Title;

            }, function (err) {
                $scope.Message = "Error " + err.status;
            });

    }

})}(angular.module('sgaapp')));

Solution

  • Man, I didn't catch what are you want to do, but I want to take you few advise:

    1. Your logic it's really complicated, you should re-think it, cause now it's sucks;

    2. Includes in angular sucks too. Really. You shouldn't use it at all. How to avoid it? Well, there is two option.

      • First is to use client-side routing (for pages); Instead of using built-in routing, better to use ui-router. You will be able to use nested states and routes;
      • Second is to use directives instead of includes. Really, just imagine - header or footer, both can be directives, which you just include in pages when it's needed.

    What for me - I use first and second solution in same time.

    1. You should avoid to put anything in $rootScope. Perhaps it's couldn't kill you, and from time to time it's the only solution, but, u know, it's a bad practice.

    2. If you need to store data and share it between controllers, the better option is to us factories (or other services, but factories most universal).

    Example:

    app.factory('MyFactory', function () {
        return {
            myData: 'some default value',
            someCommonFuction: function (a, b) {
              return a + b;
            }
        };
    });
    

    As well as data-store, you can use factory as utility-class, with common functions