Sign up ×
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them; it only takes a minute:

I am relatively new to angularJS, I am trying to set up a page where inturn multiple pages are called depending upon the selection made previously. All the pages have their own controller, so I am trying to set the controller and view src through the javascript and using them in HTML tags.

Following is what I am doing:
HTML page:

<div ng-if="sidebarName=='sidebar-device-wire'">
        <div ng-controller="getSidebarCtlr">    
            <div ng-include src="sidebarSrc"></div>
        </div>
    </div>

javascript:

$scope.sidebarSrc="views/sidebars/sidebar-device.html";
$scope.sidebarCtlr="SidebarDeviceCtrl";

$scope.getSidebarCtlr = function(){return $scope.sidebarCtlr;}

For some reason though, this does not work. i can get the HTML page but the controller is not being called. Can anyone please tell me what I am doing wrong?

share|improve this question
3  
don't do this. use ngRoute or a well tested 3rd party replacement like uiRouter instead. – Claies yesterday
    
There is a constraint, I cannot use APIs, I have to work with what I got. – Yash shah yesterday
1  
I second @Claies. Use uiRouter. – Tarun Dugar yesterday
1  
neither ngRoute nor uiRouter are APIs. – Claies yesterday
    
you can't invoke a controller by referring to it's name in a variable. What you are trying to do might work if you interpolated the function output, i.e. ng-controller="{{getSideBarCtrlr}}", but this is very abnormal, and recreating a major framework feature like this is challenging even for people very familiar with the framework. ngRoute is a core module designed to do what you are trying to do. – Claies yesterday

I would also recommend to use ngRoute or ui.router because there are many features that aren't easy to implement from scratch (like named views, nested views / nested states or resolves) and these modules are well tested.

Not sure why your controller isn't running but I guess that the expression of the controller is evaluated before your controller that is setting the name is running. So it will be always undefined at compile time.

But if you really like to implement a very basic router you could do it like in the following demo (or in this fiddle).

Update 21.12.2015

Here are some router examples that I wrote for other SO questions:

  • simple ui.router example - jsfiddle
  • more complex nested state example ui.router - jsfiddle
  • dynamic link list with ngRoute - jsfiddle

Please also have a look at ui.router github pages to learn more about it.

angular.module('simpleRouter', [])
  .directive('simpleView', simpleViewDirective)
  .provider('simpleRoutes', SimpleRoutesProvider)
  .controller('MainController', MainController)
  .controller('HomeController', HomeController)
  .config(function(simpleRoutesProvider) {
    simpleRoutesProvider.state([{
      url: '/',
      templateUrl: 'home.html',
      controller: 'HomeController'
    }, {
      url: '/view1',
      templateUrl: 'view1.html'
    }, {
      url: '/view2',
      templateUrl: 'view2.html',
      controller: function($scope) {
      	$scope.test = 'hello from controller'
      }
    }]);

    simpleRoutesProvider.otherwise('/');
  })

function HomeController($scope) {
	$scope.hello = 'hello from home controller!!';
	console.log('home controller started')
}

function MainController($scope) {
   $scope.hello = 'Main controller test';
}

function simpleViewDirective() {
  return {
    restrict: 'EA',
    scope: {},
    template: '<div ng-include="templateUrl"></div>',
    controller: function($scope, $location, $controller, simpleRoutes) {
    	var childControllerInst;
      $scope.templateUrl = simpleRoutes.currentRoute.templateUrl || simpleRoutes.otherwise.templateUrl;
      
      $scope.$watch(function() {
        return $location.path();
      }, function(newUrl) {
        //console.log(newUrl)
        $scope.templateUrl = simpleRoutes.changeRoute(newUrl);
        
        childControllerInst = $controller(simpleRoutes.currentRoute.controller || function() {}, {$scope: $scope});
        
      });
      
      $scope.$on('$destroy', function() {
      	childControllerInst = undefined;
      })
    },
    link: function(scope, element, attrs) {

    }
  }
}

function SimpleRoutesProvider() {
  var router = {
    currentRoute: {
      templateUrl: ''
    },
    states: [],
    otherwise: {},
    changeRoute: function(url) {
      var found = false;
      angular.forEach(router.states, function(state) {
        //console.log('state', state);
        if (state.url == url) {
          router.currentRoute = state;
          found = true;
        }
      });

      if (!found) router.currentRoute = router.otherwise;
      //console.log(router.currentRoute);
      return router.currentRoute.templateUrl;
    }
  };

  this.state = function(stateObj) {
    router.states = stateObj;
  };

  this.otherwise = function(route) {
  	angular.forEach(router.states, function(state) {
    	if (route === state.url ) {
    		router.otherwise = state;  	
      }
    });
    
    //console.log(router.otherwise);
  };

  this.$get = function simpleRoutesFactory() {
    return router;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="simpleRouter" ng-controller="MainController">
  <script type="text/ng-template" id="home.html">home route {{hello}}</script>
  <script type="text/ng-template" id="view1.html">view1</script>
  <script type="text/ng-template" id="view2.html">view2 {{test}}</script>

  <div simple-view="">
  </div>
  <a href="#/">home</a>
  <a href="#/view1">view1</a>
  <a href="#/view2">view2</a>
  <br/>
  {{hello}}
</div>

share|improve this answer

What's that code means? $scope.getSidebarCtlr = function(){return $scope.sidebarCtlr;}

the ng-directive requires a Controller name, its argument type is string and you cannot pass a simple function, you need to register a valid controller associating it to a module via the controller recipe.

https://docs.angularjs.org/guide/controller

angular.module('test', []).controller('TestCtrl', function($scope) {
  $scope.greetings = "Hello World";
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<section ng-app="test">
  <article ng-controller="TestCtrl">{{ greetings }}</article>
</section>

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.