Imagine a scenario with the following HTML
structure:
<div ng-app="testApp">
<div ng-controller="controller1">
{{controller1}}
</div>
<div ng-controller="controller2">
{{controller2}}
</div>
<div ng-controller="controller3">
{{controller3}}
<test-directive></test-directive>
</div>
</div>
In the section where ng-controller="controller3"
is located, there exists a custom directive.
This is how the directive is defined:
ang.directive("testDirective", function() {
return {
restrict: 'AE',
link: function (scope, elem, attrs) {
console.log(scope);
},
template: "<h3>I return $scope.controller3</h3>"
}
});
The $scope
now contains the data from ng-controller="controller3"
.
How can I associate a custom controller to it? Instead of the directive passing its parent controller, I want to pass, for example, the data of controller1.
I need to be able to pass any controller to it, as the behavior of the directive depends on the data within a specific controller.
I am unable to replace the <test-directive>
inside the required controller.
Here's a fiddle for testing purposes
var ang = angular.module('testApp', []);
ang.controller("controller1", controller1);
function controller1($scope) {
$scope.controller1 = "controller1";
}
ang.controller("controller2", controller2);
function controller2($scope) {
$scope.controller2 = "controller2";
}
ang.controller("controller3", controller3);
function controller3($scope) {
$scope.controller3 = "controller3";
}
ang.directive("testDirective", function() {
return {
restrict: 'AE',
link: function (scope, elem, attrs) {
console.log(scope);
},
template: "<h3>I return $scope.controller3</h3>"
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.min.js"></script>
<div ng-app="testApp">
<div ng-controller="controller1">
{{controller1}}
</div>
<div ng-controller="controller2">
{{controller2}}
</div>
<div ng-controller="controller3">
{{controller3}}
<test-directive></test-directive>
</div>
</div>
Real-life situation:
I have created a pagination directive. This directive can be included by using
<ng-pagination></ng-pagination>
anywhere on the webpage.
The directive generates a pagination based on a provided dataset. The dataset itself can contain various types of information and is not tied to specific values or requirements.
There is one key condition for this directive. It scans the associated controller to see if there is a $scope
named $scope.result
. This variable gets populated with data fetched from an API call.
The pagination then organizes this data into pages, each displaying up to 10 results.
One challenge I'm facing is that the ng-controller
can be placed anywhere on the page along with the
<ng-pagination></ng-pagination>
.
What I aim to achieve is something like this:
I assign a data attribute to the [ng-pagination]
element. This attribute is called data-controller
. By specifying the controller name in this attribute, the directive gains access to all the data within that controller.
It would look like this:
<ng-pagination data-controller="controller1" show-next="true" ...></ng-pagination>
UPDATE
I discovered that you can assign a controller using the following syntax:
ang.directive("directive", function() {
return {
controller: "[CONTROLLER NAME]"
}
});
Therefore, I thought maybe this could work:
ang.directive("directive", function() {
return {
controller: "{{controller}}",
link: function (scope, elem, attrs) {
$scope.controller = "[CONTROLLER NAME]"
}
}
});
Unfortunately, the above approach triggers this error:
Error: ng:areq Bad Argument
Argument '{{controller}}' is not a function, got undefined