1

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.

6
  • what did you want it to do when you changed to Report 2? right now your case statement doesn't handle it. Commented Jul 2, 2015 at 14:15
  • I haven't dealt with Report 2 yet. Just trying to fix issue with Report 1. But eventually, Selecting, Report 2 will load Report2.html (Report2Ctrl.js) Commented Jul 2, 2015 at 14:16
  • yes, but you have multiple options for that dropdown, and right now you're only handling a single option. You aren't referencing SetId anywhere in your code, and no matter which of the two dropdowns call the function, they are only setting Report1.html. Commented Jul 2, 2015 at 14:18
  • For now it's only Report1. The data of Report1 changes with Sets1 & Set2. For simplicity, I haven't included the code where the Chosen setId is assigned to a global variable. At page load it all works fine. When Selected Set2, I am expecting the data in the table to change. But it doesnt. The console.log isnt also working as if, Report1Ctrl is not being hit at all. No JS errors in console. Commented Jul 2, 2015 at 14:22
  • there isn't anything setting a global variable? your dropdown is referencing SetId, your controller is looking for setId, and calling ShowReport() may change $scope.ReportTemplate but that's not going to regenerate the ng-include or call Report1Ctrl.js again..... Commented Jul 2, 2015 at 14:25

3 Answers 3

1

can you try this?

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

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

0

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

3 Comments

If a directive is used, will it auto update when a scope variable gets changed in indexCtrl.js ?
No, what I meant was, in the Question above, if $scope.SetId is changed, will it auto update the directive ? Could you give an example how a directive for this should be like?
if directive has different scope then use $scope.$parent.main.awesomeThings.push("Directive Object");

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.