Im learning about Angular directive
s and I can't wrap my head around the scope
topic. Suppose I have this custom directive
which is named parentDirective
. It has a controller
property and a link
property, as follows:
angular.module("app").directive("parentDirective", function () {
return {
restrict: "E",
templateUrl: "dirs/parent.html",
scope:{
character: "="
},
controller: function ($scope) {
$scope.getData = function (data) {
console.log(data);
}
},
link: function (scope,elem, attrs) {
elem.bind("click", function (e) {
//get object here?
});
scope.getData = function (data) {
console.log(data);
}
}
}
});
Its template is defined as follows:
<p ng-click="getData(character)">
{{character.name}}
</p>
I can get the character
object in the controller
function through the $scope
variable and I have access to the same data in the link
function through scope
. Whats the difference between the two methods in this regard? Second question, Is it possible to bind a click
to the directive
and get the object like this:
elem.bind("click", function (e) {
//get object here?
});
Scope is specific to current directive instance and is the same object in both functions.
For defining methods on the scope, there's no difference if they are defined in controller or link function, unless there is race condition that requires the method to be defined as early as possible. For this reason it makes sense to define scope methods in controller.
Event handler doesn't differ from any other function, it is
elem.on("click", function (e) {
scope.$apply(function () {
scope.character...
});
});
scope.$apply(...)
wrapper doesn't hurt anyway, but the necessity of it depends on what happens with scope.character
.
The directive can have only controller
and no link
. Current Angular versions (1.5+) suggest the style where bindToController
+ controllerAs
are used instead of scope
bindings as common ground for directives and components.
Then the directive may look like
restrict: "E",
template: '<p>{{$ctrl.character.name}}</p>',
controllerAs: '$ctrl',
bindToController: { character: "=" },
controller: function ($element, $scope) {
var self = this;
self.getData = function (data) { ... };
$element.on("click", function (e) {
scope.$apply(function () {
self.character...
});
});
}
link
function may appear as $postLink
controller hook, but here it is not needed.