isolate scope on a directive restricted to attributes - javascript

In the documentation for directives you can isolate scope with the following:
.directive('myDialog', function() {
return {
restrict: 'E',
transclude: true,
scope: {
'close': '&onClose'
},
templateUrl: 'my-dialog-close.html'
};
});
I'm trying to write a directive that is restricted to attributes. How do I get the same isolate functionality when restricting with 'A'?
.directive('doSomething', function() {
return {
restrict: 'A',
scope: {
'close': '&???'
},
link: function(scope, element, attrs) {
element.on('click', function() {
scope.close();
});
}
};
});
I would use the directive like so:
<button do-something="doSomething()" type="button">Do Something</button>

Isolated scope doesn't depends on the the restrict property. You need to mention those variable/ method in isolated scope which you are going to pass from the parent scope.
As in below isolate scope declaration you have used close as isolated scope variable which will accept method, that means you should pass that method instance in close attribute.
scope: {
close: '&' //it shouldn't be with quotes
},
Markup
<button do-something close="doSomething()" type="button">Do Something</button>
Edit
If you wanted to alias your attribute name, then it that alias would be there after the & like close: '&myAlias', by using alias you could avoid the execution of other directive (Ideally your directive shouldn't have name like that)
scope: {
close: '&myAlias' //it shouldn't be with quotes
},
Markup
<button do-something my-alias="doSomething()" type="button">Do Something</button>

Related

Passing Function Arguments with Isolated and Share scopes with Angular Directives

I have 3 directive with isolate scope and share scope and I want pass a function beteween outermost a innermost directive. The outer and middle has isolate scopes and the middle with inner share the scope. Any suggest ?
Pass the functions of my controller as shown below .
<outer on-edit="helloWorld" ng-model="model" ng-repeat="items in items.objects" ></outer>
In my controller:
$scope.helloWorld = function(){
alert('Hello world');
}
My directive:
angular.module('myApp')
.directive('outer', function () {
return {
restrict: 'E',
replace: true,
scope: {
item: "=ngModel",
onEdit: '&'
},
template: '<div><middle on-edit='onEdit'></middle></div>',
controller : function($scope){
$scope.edit = function(){
$scope.onEdit()();
}
}
};
})
.directive('middle', function () {
return {
restrict: 'E',
replace: true,
scope: {
item : '=ngModel',
onEdit : '&'
},
templateUrl: '<div><inner on-edit='onEdit'></inner></div>'
};
})
.directive('inner', function () {
return {
restrict: 'E',
template: '<div><a ng-click='edit()'>Edit</a></div>'
};
})
And this not work, any ideas?
Thanks
This looks a bad design though, but in the middle directive's template you are using inner directive as follows:
<div><inner on-edit='onEdit'></inner></div>
If you look at it, inner directive has no scope, so the attribute on-edit doesn't make sense there.
If you want to use any method that is present in middle directive can be directly used in inner directive because of shared scope. Think of inner directive as a part of html written in some other html file which will be replaced at run time.
So anything you pass to middle directive is implicitly passed to inner.

"Scope" in directive linking function is the root scope, not directive scope

I have a directive as follows
.directive('ticketingChat', function() {
return {
restrict: 'E',
templateUrl: '/Reply/ReplyScreen', //cshtml from MVC page
controller: 'TicketingChatController',
link: function (scope, el, attr) {
scope.writingTo = "Hey there!";
}
}
})
I thought that this would create it's own scope, and "scope" would allow me to access it.
Instead, ng-inspector shows me that:
"Scope" is in fact, the root scope. How can I force the directive to create it's own child scope?
And how can I access that scope from the linking function?
Setting scope: true in the directive definition object will make AngularJS create an inheriting child scope. Setting scope to an object will create an isolated child scope.
For example:
.directive('ticketingChat', function() {
return {
restrict: 'E',
templateUrl: '/Reply/ReplyScreen',
controller: 'TicketingChatController',
scope: true,
link: function (scope, el, attr) {
scope.writingTo = "Hey there!"; // This will be set on the child scope because we have scope: true.
}
}
})
See the docs for more details regarding the scope attribute.

Multiple directives with individual scopes for one element

Can the one element have multiple directives with individual scopes?
Let's say, we have custom directive's child with the controller's scope and any directive (here is "ng-class"):
<custom-directive data-model="model">
<input class="child" data-ng-class="controllerScopeValue">
</custom-directive>
Now we want to add extra directive with isolated scope to the child. Something like this:
angular.module('core').directive('customDirective', [function($compile) {
return {
scope: {
'model': '='
},
compile: function(templateElement, templateAttrs) {
templateElement.children().attr('data-ng-model', 'directiveScopeValue');
return function($scope) {
$scope.directiveScopeValue = 'directive\'s scope value';
}
}
};
}]);
So, how to keep individual scopes for each directive?
no that is not possible, if you try to do it, you will get error similar to
Multiple directives [myDirective1, myDirective2] asking for new/isolated scope
plunker
ignore below dummy code
app.directive('myDirective1', ['$document',
function ($document) {
return {
restrict: 'A',
replace: false,
scope : {},
and
app.directive('myDirective2', ['$document',
function ($document) {
return {
restrict: 'A',
replace: false,
scope : {},

Creating a directive which inherit parent scope as well as have some additional properties

i read Angularjs documentation .In directives i can use parent scope for current directive by not speciying scope attribute like this
.directive('myCustomer', function() {
return {
restrict: 'E',
templateUrl: 'my-customer.html'
};
});
and i can create a directive with isolated scope in this way
.directive('myCustomer', function() {
return {
restrict: 'E',
scope: {
customerInfo: '=info'
},
templateUrl: 'my-customer-iso.html'
};
});
what if i want to inherit all properties of parent scope and want to add some properties related to this directive .i want to create a new scope when this directive is used but not an isolated scope.How to acheive that ??

difference between isolated scope + binding name and isolated scope only in AngularJS

i'm learning directives in AngularJS, and found that in a few examples, when adding an isolated scope (#, = or &). They sometimes add not only the isolated scope, but also the ngModel name after it. i.e.: "#name" instead of only "#".
So what's the difference between:
myApp.directive('zippy', function() {
return {
restrict: "E",
transclude: true,
replace: true,
scope: {
name: "#" // <----
},
template: "<div>{{name}}<div ng-transclude></div></div>",
link: function(scope, element, attrs) {
console.log(scope.name);
}
}
});
And this:
myApp.directive('zippy', function() {
return {
restrict: "E",
transclude: true,
replace: true,
scope: {
name: "#name" // <----
},
template: "<div>{{name}}<div ng-transclude></div></div>",
link: function(scope, element, attrs) {
console.log(scope.name);
}
}
});
This is from the developer guide
For cases where the attribute name is the same as the value you want
to bind to inside the directive's scope, you can use this shorthand
syntax:
...
scope: {
// same as '=customer'
customer: '='
},
...
Means you can use name: "#" in your directive if your have same name html attribute where directive is declared
<div zippy name="myName"></div>
Remember attribute name should match not the expression in the attribute. It can be any property on scope.

Categories