Given this fairly simple angular wrapper for a JQuery UI button:
angular.module('Sample.controllers', [])
.controller('mainController', ['$scope',
function($scope) {
$scope.jump = function () {alert("jump");};
}])
.directive('jquiwButton', function() {
return {
scope: {},
restrict: 'A',
replace:true,
link: function(scope, element, attrs) {
var options = {};
if (angular.isDefined(attrs["jquiDisabled"])) {
options.disabled = attrs["jquiDisabled"];
}
if (angular.isDefined(attrs["jquiIconPrimary"])) {
if (!angular.isDefined(options.icons.primary)) {
options.icons ={};
}
options.icons.primary = attrs["jquiIconPrimary"];
}
if (angular.isDefined(attrs["jquiIconSecondary"])) {
if (!angular.isDefined(options.icons.secondary)) {
options.icons ={};
}
options.icons.secondary = attrs["jquiIconSecondary"];
}
if (angular.isDefined(attrs["jquiLabel"])) {
options.label = attrs["jquiLabel"];
}
if (angular.isDefined(attrs["jquiText"])) {
options.text = attrs["jquiText"];
}
element.button(options);
}
};
});
angular.module('Sample', ['Sample.controllers']);
And the markup.
<body ng-controller="mainController">
<button jquiw-button jqui-label="Hello" ng-click="jump()">Hello</button>
</body>
and it works fine until I add a scope at which point I lose the ability to use the standard angular bindings to the outer scope. In my case the markup `ng-click='jump()' now won't work because it can't find the method jump which is defined in the outer context and not in the isolate scope. Now I know that I can specifically bind ng-click back to the outer scope but I want to avoid doing that since it requires knowledge of all the possible directives I might need to bind.
So my question is: How do I let other directives work in the outer scope while still having an isolate scope?
plunker: http://plnkr.co/edit/eRoOeq?p=preview
Remove line 8: scope: {}, and it ng-click calls the correct function.
-
I don't think it is possible to do that.... still have a look at how ng-repeat is implemented....Arun P Johny– Arun P Johny2013年09月30日 02:40:44 +00:00Commented Sep 30, 2013 at 2:40
2 Answers 2
Use ng-click="$parent.jump()".
2 Comments
You can reference a function in the parent scope from inside the isolate scope by using the & binding. This is the proper way to call a function from an isolate scope inside a directive according to the directive documentation.
I created a working CodePen example to demonstrate it working flawlessly.
Here's the relevant parts:
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
$scope.jump = function() {
alert('jump called');
};
});
app.directive('myDirective', function() {
return {
restrict: 'E',
scope: {
call: '&'
},
link: function postLink(scope, element, attrs) {
scope.call();
}
};
});
and in the template:
<section ng-app="app" ng-controller="MainCtrl">
<my-directive call="jump()"></my-directive>
</section>
I hope this helps.
4 Comments
ng-click or ng-blur on your element without consulting your directive documentation, then they are taking their own chances. Potential users of your new directive should be aware that your directive uses specific attributes.ng-* directives on our custom directives without explicitly binding them in the isolate scope. What I am finding is that even among native angular directives they don't always place nice together. That leads me to believe that the prescribed usage be strictly adhered to. That further leads me to believe that dictating usage of our own custom directives is acceptable.