Isolating the $scope From the Directive
In the example above the userinfo
directive was bound hard to the $scope
variable because the HTML template referenced the textToInsert
property directly. Referencing $scope
variables directly makes it hard to reuse the directive more than once within the same controller, since the $scope
variables typically have the same values everywhere inside the same controller. For instance, if you wanted to have this HTML in your page:
<userinfo></userinfo> <userinfo></userinfo>
Then the two <userinfo>
elements would be replaced by the same HTML template, which is bound to the same $scope
variable. The result would be that the two <userinfo>
elements would be replaced by the exact same HTML code.
To be able to bind the two <userinfo>
elements to different values in the $scope
object, you need to bind the HTML template to an isolate scope.
An isolate scope is a separate scope object tied to the directive. Here is how you define it in the directive definition object:
myapp.directive('userinfo', function() { var directive = {}; directive.restrict = 'E'; directive.template = "User : {{user.firstName}} {{user.lastName}}"; directive.scope = { user : "=user" } return directive; })
Notice how the HTML template has two interpolation directives bound to {{user.firstName}}
and {{user.lastName}}
. Notice the user.
part. And notice the directive.scope
property. The directive.scope
property is a JavaScript object which contains a property named user
. The directive.scope
property is the isolate scope object, and the HTML template is now bound to the directive.scope.user
object (via the {{user.firstName}}
and {{user.lastName}}
interpolation directives).
The directive.scope.user
property is set to "=user"
. That means, that the directive.scope.user
property is bound to the property in the scope property (not in the isolate scope) with the name passed to the user
attribute of the <userinfo>
element. It sounds confusing, so look at this HTML example:
<userinfo user="jakob"></userinfo> <userinfo user="john"></userinfo>
These two <userinfo>
element contain a user
attribute. The value of these attributes contain the names of properties in the $scope
object which are to be referenced by the isolate scope object's userinfo
property.
Here is a full example:
<userinfo user="jakob"></userinfo> <userinfo user="john"></userinfo> <script> myapp.directive('userinfo', function() { var directive = {}; directive.restrict = 'E'; directive.template = "User : <b>{{user.firstName}}</b> <b>{{user.lastName}}</b>"; directive.scope = { user : "=user" } return directive; }); myapp.controller("MyController", function($scope, $http) { $scope.jakob = {}; $scope.jakob.firstName = "Jakob"; $scope.jakob.lastName = "aitechtonic"; $scope.john = {}; $scope.john.firstName = "John"; $scope.john.lastName = "Doe"; }); </script>