eekboom
eekboom

Reputation: 5802

Why can't my directive require a controller created by angular-ui-router?

I am trying to write a directive that requires a parent controller that is configured in an angular-ui-router state definition.

Directive "beep" has require: '^subController

"subController" is the controller for a view configured in angular-ui-router.

That view contains an element that uses the directive "beep".

However: There is an exception that says "subcontroller cannot be found" as soon as I navigate to the substate.

Bug in angular-ui-router? Some misunderstanding on my side?

To reproduce: Just click on "Run code snippet" and then click on the "Sub State" button:

angular
	.module('foo', ['ui.router'])

	.controller('subController', function () {
		console.log("subController");
	})

	.config(function ($stateProvider, $urlRouterProvider) {

		$urlRouterProvider.otherwise("/root");

		$stateProvider
			.state('root', {
				url: '/root',
				views: {
					root: {
						template: '<button ui-sref="root">Root State</button>' +
						'<button ui-sref="root.sub">Sub State</button>' +
						'<div ui-view="sub"></div>'
					}
				}
			})

			.state('root.sub', {
				url: '/sub',
				views: {
					sub: {
						controller: 'subController',
						template: '<div beep>SUB</div>'
					}
				}
			});

	})

	.directive('beep', function () {
		return {
			restrict: 'A',
			require: '^subController',
			link: function (scope, element, attributes, subController) {
				console.log("beep: linked", subController);
			}
		};
	})
;
<!DOCTYPE html>
<html lang="en">
	<head>
		<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.0/angular-ui-router.js"></script>
		<script src="app.js"></script>
	</head>
	<body ng-app="foo">
		<div class="root-view" ui-view="root"></div>
		<pre id="errors" style="color: #e22; margin-top: 20px;"></pre>
	</body>

</html>

Upvotes: 4

Views: 823

Answers (2)

Walfrat
Walfrat

Reputation: 5353

You can't search for a controller, you can only search for a directive in the same element or a parent element.

When you have that directive, the controller of that directive will be passed as a 4th argument of the link function.

Furthermore controller of directives and controller bind to view/state/ng-controller are differents concepts. A directive's controller has no scope, it's used to expose an API to other directives, the most known is the controller of ngModel.

If you need to be in a particular state/controller for your directive, that mean you have something wrong in your design. Tell us what functionnality you want to do and we can help you how to design it in angular.

Upvotes: 2

Suraj Sharma
Suraj Sharma

Reputation: 857

'require' in the directive is to include parent directive not the controller. one way of using the subController is by including controller:subController in the directive 'beep'

Upvotes: 0

Related Questions