Reputation: 4328
I have this fiddle that shows a directive that has an alert for now. There is also a controller that has alert. This is all working fine except for the fact that the binding is being lost for the text to be shown on the button. Any ideas to help me?
<div ng-app="directiveApp" ng-controller="MainController">
<button ng-click="doStuff()" unsaved-warning-trigger>
{{buttonText}}
</button>
</div>
var app = angular.module("directiveApp", []);
app.directive('unsavedWarningTrigger',
function() {
return {
priority: 1,
terminal: true,
link: function (scope, element, attr) {
var clickAction = attr.ngClick;
element.bind('click',function () {
if (window.confirm("Sure?")) {
scope.$eval(clickAction)
}
});
}
};
}
);
MainController = function($scope) {
$scope.buttonText = 'bound button';
$scope.doStuff = function () {
alert("doing stuff");
};
}
Upvotes: 0
Views: 270
Reputation: 457
That is happening to you because of setting the "terminal" property to "true". By doing this, you are preventing any other directives that come later to execute (even if they are not explicit).
Think about your requirements and whether you really need to set
'terminal: true'
Otherwise, you should follow a different scope approach.
I attach a jsFiddle where you can see the binding work by removing that property:
and a good post about the terminal and priority properties:
EDIT:
However, to achieve the whole functionality you want, you can write your directive as:
app.directive('unsavedWarningTrigger',
function() {
return {
priority: 1,
terminal: true,
link: function (scope, element, attr) {
element.text(scope.buttonText);
var clickAction = attr.ngClick;
element.bind('click',function () {
if (window.confirm("Sure?")) {
scope.$eval(clickAction)
}
});
}
};
}
);
See jsFiddle:
Take into account that with this implementation, the button text is only set once at the directive link time. Since the binding with buttonText has been broken by the property 'terminal: true', if you want the button text to update upon changes of the variable buttonText, you would need to set a $watch for it and execute the element.text(scope.buttonText) within it.
Best.
Upvotes: 1
Reputation: 26858
'terminal: true'
prevents all directives with a lower priority on that element from being executed. But it also prevents directives from child elements from being executed.
Angular adds a directive for an {{expression}}
. In your case the directive is added to the text node, the child of the button
element. But because of terminal: true
, that directive is never executed.
Upvotes: 1