Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it Possible to Update Parent Scope from Angular Directive with scope: true?

I have a need for inheriting scope from a parent controller in a directive. I don't necessarily want to leave scope: false. I also don't necessarily want to use an isolated scope, because it requires a lot of work to get the values I do care about linked properly (think lots of values in a parent controller).

Does it make sense to use scope:true in my directive if I want to update parent scope?

<div ng-controller="MyCtrl">       Hello, {{name}}!         <my-directive></my-directive> </div> 
var myApp = angular.module('myApp',[]);  //myApp.directive('myDirective', function() {}); //myApp.factory('myService', function() {});  function MyCtrl($scope) {     $scope.name = 'Dave'; }   myApp.directive('myDirective', function() {     return {         scope: true,         restrict: 'EA',         link: function(scope, elem, attrs) {             scope.updateName = function(newName) {                 console.log('newName is: ' + newName);                 scope.name = newName;             }         },         template: '<input ng-model="updatedName" placeholder="new name value"> <button ng-click="updateName(updatedName)">Update</button>'     } }) 

Please check out the fiddle

like image 724
binarygiant Avatar asked May 30 '13 20:05

binarygiant


People also ask

How do I get parent scope in directive?

You can still access the parent scope using $parent , but this is not normally recommended. Instead, you should specify which parent scope properties (and/or function) the directive needs via additional attributes on the same element where the directive is used, using the = , @ , and & notation.

What is the best scope to be used for reusable directives in AngularJS?

Isolate Scope: If the need is to reuse the component (directive) throughout your app, consider creating isolate scopes using scope option. The concept of isolate scope is used to separate the scope inside a directive from the scope outside.

Can we use multiple directives in AngularJS?

... is quite illustrative as AngularJS doesn't allow multiple directives (on the same DOM level) to create their own isolate scopes. According to the documentation, this restriction is imposed in order to prevent collision or unsupported configuration of the $scope objects.

How does a parent $scope relate to a child scope?

Angular scopes include a variable called $parent (i.e. $scope. $parent ) that refer to the parent scope of a controller. If a controller is at the root of the application, the parent would be the root scope ( $rootScope ). Child controllers can therefore modify the parent scope since they access to it.


2 Answers

Although @user1737909 already referenced the SO question to read (What are the nuances of scope prototypal / prototypical inheritance in AngularJS?, which will explain the problem and recommended various ways to fix it), we normally try to give the answer on SO.

So, the reason your fiddle doesn't work is because when a primitive type (i.e., a string, number, or boolean type) is written to -- e.g., scope.name = newName -- the "write" always goes to the local scope/object. In other words, the child scope gets its own name property that shadows the parent property of the same name. The fix is to use an object, rather than a primitive type, in the parent scope. The child scope will then get a reference to that object. Any writes to the object properties (whether from the parent or the child) will go to that one object. (The child scope does not get its own object.)

$scope.obj = {name: 'Dave'}; 

Then in your directive:

scope.obj.name = newName; 

and HTML:

Hello, {{obj.name}}! 

fiddle

like image 122
Mark Rajcok Avatar answered Nov 05 '22 04:11

Mark Rajcok


Scope inheritance is not meaning setting the value of a child is setting the value of its parent.

Instead of doing scope.name = newName on the child scope, add a method to the parent scope, which will do the same job but on the parent scope, and call it from the child scope since the child inherits this method.

like image 38
lib3d Avatar answered Nov 05 '22 05:11

lib3d