Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing variable to directive template without creating new scope

Is there a way to pass variables using attributes to a directive without creating a new scope ?

HTML

<div ng-click='back()' button='go back'></div> 

JS

.directive('button', function () {     return {         scope: {             button: '@'         },         template: "<div><div another-directive></div>{{button}}</div>",         replace: true     } }) 

The problem is that the ng-click='back()' now refers to the directive scope. I still can do ng-click='$parent.back()' but it's not what I want.

like image 343
Seb Fanals Avatar asked May 15 '13 09:05

Seb Fanals


People also ask

How to declare variable in template Angular?

In the template, you use the hash symbol, # , to declare a template variable. The following template variable, #phone , declares a phone variable with the <input> element as its value. Refer to a template variable anywhere in the component's template.

How to pass scope to directive AngularJS?

The directive scope uses prefixes to achieve that. Using prefixes helps establish a two-way or one-way binding between parent and directive scopes, and also make calls to parent scope methods. To access any data in the parent scope requires passing the data at two places – the directive scope and the directive tag.

Which syntax can be used to create a new directive called directive?

New directives are created by using the . directive function. To invoke the new directive, make an HTML element with the same tag name as the new directive.

What is the default scope in an Angular directive?

scope: false: This directive is used by default in isolated scope and it is mainly used to reuse the scope from the component it is currently being used at. scope: true: This directive is used to create a child scope and it prototypically inherits the parent scope.


1 Answers

By default, directives do not create a new scope. If you want to make that explicit, add scope: false to your directive:

<div ng-click='back()' button='go back!'></div> 
angular.module('myApp').directive("button", function () {     return {         scope: false,  // this is the default, so you could remove this line         template: "<div><div another-directive></div>{{button}}</div>",         replace: true,         link: function (scope, element, attrs) {            scope.button = attrs.button;         }     }; }); 

fiddle

Since a new property, button, is being created on the scope, you should normally create a new child scope using scope: true as @ardentum-c has in his answer. The new scope will prototypially inherit from the parent scope, which is why you don't need to put $parent.back() into your HTML.

One other tidbit to mention: even though we are using replace: true, clicking the element still calls back(). That works because "the replacement process migrates all of the attributes / classes from the old element to the new one." -- directive doc
So ng-click='back()' button='go back!' are migrated to the first div in the directive's template.

like image 184
Mark Rajcok Avatar answered Sep 20 '22 10:09

Mark Rajcok