Steve
Steve

Reputation: 14912

Sub-views in Angular UI router and Controller inheritance?

I have a view state like this, with 3 views:

    (function() {

  'use strict';

  angular.module('pb.tracker').config(function($stateProvider) {
    $stateProvider.state('tracker', {
        url: '/tracker',
        controller: 'TrackerController as tracker',
        data: {
          pageTitle: 'Parcel Tracker',
          access: 'public',
          bodyClass: 'tracker'
        },
        resolve: {
          HistoryResolve: function($log, MockDataFactory) {
            return MockDataFactory.query({
              filename: 'trackingdata'
            });
          }
        },
        views: {
          '': {
            templateUrl: 'modules/tracker/templates/tracker.html'
          },
          'controls@tracker': {
            templateUrl: 'modules/tracker/templates/tracker-controls.html'
          },
          'content@tracker': {
            templateUrl: 'modules/tracker/templates/tracker-details.html'
          }
        }
      });

  });

})();

I want to use the controller TrackerController for all the views in the state. I thought they would simple inherit the parent one.

But so far, even a simple log does not show in the console. The controller is

    (function() {

  'use strict';

  angular.module('pb.tracker').controller('TrackerController', function($log, HistoryResolve) {

    var _this = this;

    // _this.packageHistory = HistoryResolve;

    $log.debug('foo');


  });

})();

So, my console should read "foo" regardless, yes? Nothing in the console. No errors. The works fine, the views load the templates. I am only stuck on the controller. I've never run into this.

UPDATE OK, I am trying to define a parent state, and assign the controller to that. However, what I have below is no yielding nothing at all in the browser...

    (function() {

  'use strict';

  angular.module('pb.tracker').config(function($stateProvider) {
    $stateProvider.state('tracker', {
        url: '/tracker',
        abstract: true,
        controller: 'TrackerController as tracker',
        data: {
          pageTitle: 'Parcel Tracker',
          access: 'public',
          bodyClass: 'tracker'
        },
        resolve: {
          HistoryResolve: function($log, MockDataFactory) {
            return MockDataFactory.query({
              filename: 'trackingdata'
            });
          }
        }
      })
    .state('tracker.details', {
        url: '/tracker/details',
        views: {
          '': {
            templateUrl: 'modules/tracker/templates/tracker.html'
          },
          'controls@tracker': {
            templateUrl: 'modules/tracker/templates/tracker-controls.html'
          },
          'content@tracker': {
            templateUrl: 'modules/tracker/templates/tracker-details.html'
          }
        }
      });

  });

})();

Upvotes: 3

Views: 250

Answers (1)

Sunil D.
Sunil D.

Reputation: 18193

When you define named views (using the views property, aka "named views"), the template properties of the state are overriden by each named view. From the documentation:

If you define a views object, your state's templateUrl, template and templateProvider will be ignored. So in the case that you need a parent layout of these views, you can define an abstract state that contains a template, and a child state under the layout state that contains the 'views' object.

Note that a template is always paired with a controller. So since it doesn't use the template properties, there's no need for it to instantiate the controller. You have two choices:

  • Use specify the controller for each view. This will instantiate a controller for each named view, probably not what you want.
  • Create a parent state to this state, which is abstract and uses the controller. Note that your state above doesn't have a child/parent relationship, it's just one state w/some named views.

Upvotes: 1

Related Questions