sukesh
sukesh

Reputation: 2437

Communicating between controllers - angularjs

This is a simple app with - 1 page, 1 view, 2 Controllers and 1 Factory.

The page has two dropdowns where user can choose a report and a set. On selection of either, it will display related table inside ng-include. Report1 & Report2 are different in data & in table structure. So, I have a different html for each report.

At page load, by default, the report selected is Report 1 and Set is Set 1. The data loads fine. The text "one" is also displayed in the console. But, when I select Set 2, nothing happens.

Is it because Report1.html is already loaded ? I think I have to use a shared service, but do not know, how to use it in this case.

index.html:

<div ng-controller="indexCtrl">
 <select id="ddlReports" ng-model="ReportId">
   <option value="1">Report 1</option>       
 </select>
 <select id="ddlSets" ng-model="SetId" ng-change="ShowReport()">
   <option value="1">Set 1</option>
   <option value="2">Set 2</option>
 </select>
 <br/>
 <ng-include src="ReportTemplate"></ng-include>
</div>

indexCtrl.js:

$scope.ShowReport = function () {
   GlobalVariable.SetId = $scope.SetId;
   switch ($scope.ReportId) {
      case 1:                
            $scope.ReportTemplate = "Report1.html";              
            break;            
    }
};

Report1.html:

<div ng-controller="Report1Ctrl">
 <table>
   <thead>
            <tr>
                <th>#</th>
                <th>Mobile No.</th>
                <th>Circle</th>                
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="response in Report1 track by $index">
                <td>{{$index + 1}}</td>
                <td>{{response.MobileNo}}</td>
                <td>{{response.Circle}}</td>                
            </tr>
        </tbody>
 </table>
</div>

Report1Ctrl.js:

//setId is a global variable
console.log("one");
    var promise = ReportsFactory.GetReport(GlobalVariable.SetId);
    promise.then(function (success) {
        if (success.data != null && success.data != '') {
            $scope.Report1 = JSON.parse(success.data);
        }
        else {
            console.log(success.data);
        }
    },
    function (error) {
        console.log(error);
    })

From what I understand, ng-include is not being regenerated and or Report1Ctrl.js is being called again. What should be done to correct that.

Upvotes: 1

Views: 66

Answers (3)

Parmod
Parmod

Reputation: 1243

Instead of ng-include you should use custom angular directive and render as per your choice.

main.html

{{main.awesomeThings}}
<custom-demo-directive></custom-demo-directive>

main.js

angular.module('demoAppApp')
  .controller('MainCtrl', function () {
    this.awesomeThings = [
      'HTML5 Boilerplate',
      'AngularJS',
      'Karma'
    ];
  });

directive.js

(function() {
    'use strict';
    angular
        .module('demoAppApp')
        .directive('customDemoDirective', customDemoDirective);

    customDemoDirective.$inject = ['$rootScope'];

    /* @ngInject */
    function customDemoDirective ($rootScope) {
        // Usage:
        //
        // Creates:
        //
        var directive = {
            bindToController: true,
            controller: directiveController,
            controllerAs: 'vm',
            link: link,
            templateUrl: '/views/directive-template.html',
            restrict: 'E',
        };
        return directive;

        function link(scope, element, attrs) {
            console.log("link");
        }
    }

    /* @ngInject */
    function directiveController ($scope) {
        $scope.main.awesomeThings.push("Directive Object");
        console.log($scope.main.awesomeThings);
    }
})();

Upvotes: 0

GeoffreyB
GeoffreyB

Reputation: 1839

You should emit an event on the $rootScope and listen for this event in your Report1Ctrl (take a look at $emit and $on in the documentation: https://docs.angularjs.org/api/ng/type/$rootScope.Scope).

When you receive the event, you should just refresh your display. Events are one of the ways to communicate between controllers.

Upvotes: 1

&#246;zg&#252;r kara
&#246;zg&#252;r kara

Reputation: 79

can you try this?

$scope.ReportTemplate = "'Report1.html'";

Upvotes: 1

Related Questions