Angularjs: set parent directive scope value with child directive

angularjs, angularjs-directive, angularjs-scope

Solution

If you want that kind of communication, you need to use `require` in the child directive. That will require the parent `controller` so you need a `controller` there with the functionality you want the children directives to use.

For example:

app.directive('parent', function() {
  return {
    restrict: 'E',
    transclude: true,
    template: '<div>{{message}}<span ng-transclude></span></div>',
    controller: function($scope) {
      $scope.message = "Original parent message"

      this.setMessage = function(message) {
        $scope.message = message;
      }
    }
  }
});

The controller has a message in the `$scope` and you have a method to change it.

Why one in `$scope` and one using `this`? You can't access the `$scope` in the child directive, so you need to use `this` in the function so your child directive will be able to call it.

app.directive('child', function($timeout) {
  return {
    restrict: 'E',
    require: '^parent',
    link: function(scope, elem, attrs, parentCtrl) {
      $timeout(function() {
        parentCtrl.setMessage('I am the child!')
      }, 3000)
    }
  }
})

As you see, the link receives a fourth param with the parentCtrl (or if there is more than one, an array). Here we just wait 3 seconds until we call that method we defined in the parent controller to change its message.

See it live here: http://plnkr.co/edit/72PjQSOlckGyUQnH7zOA?p=preview

Problem

I'm not sure this is the way to do this, but my goal is the following: - I have a parent directive - Inside the parent directive's block, I have a child directive that will get some input from the user - The child directive will set a value in the parent directive's scope - I can take it from there Of course the problem is that the parent and child directives are siblings. So I don't know how to do this. Note - I do not want to set data in the Fiddle: http://jsfiddle.net/rrosen326/CZWS4/ html: ``` <div ng-controller="parentController"> <parent-dir dir-data="display this data"> <child-dir></child-dir> </parent-dir> </div> ``` Javascript ``` var testapp = angular.module('testapp', []); testapp.controller('parentController', ['$scope', '$window', function ($scope, $window) { console.log('parentController scope id = ', $scope.$id); $scope.ctrl_data = "irrelevant ctrl data"; }]); testapp.directive('parentDir', function factory() { return { restrict: 'ECA', scope: { ctrl_data: '@' }, template: '<div><b>parentDir scope.dirData:</b> {{dirData}} <div class="offset1" ng-transclude></div> </div>', replace: false, transclude: true, link: function (scope, element, attrs) { scope.dirData = attrs.dirData; console.log("parent_dir scope: ", scope.$id); } }; }); testapp.directive('childDir', function factory() { return { restrict: 'ECA', template: '<h4>Begin child directive</h4><input type="text" ng-model="dirData" /></br><div><b>childDir scope.dirData:</b> {{dirData}}</div>', replace: false, transclude: false, link: function (scope, element, attrs) { console.log("child_dir scope: ", scope.$id); scope.dirData = "No, THIS data!"; // default text } }; }); ```

Original source