0

I have a simple parent/child controller set up as follows:

<body ng-controller="ParentCtrl">

    <section my-directive></section>

    <div ng-controller="Child1Ctrl">
        <button ng-click="child1()">Click Child1</button>
    </div>

    <br>

    <div ng-controller="Child2Ctrl">
        <button ng-click="child2()">Click Child2</button>
    </div>

</body>

When i click on either button, from Child1Ctrl OR Child2Ctrl, i want the scopes within my-directive to be updated.

myDirective.js

app.directive('myDirective', function () {

    var slider = {
        initial : function() {
            slider.clear();
            $scope.slideHide = false;
            $scope.slideShow = false;
        },
        clear: function() {
            $scope.slideMessage = '';
            $scope.slideError = false;
            $scope.slideSuccess = false;
        },
        error: function(message) {
            $scope.slideShow = true;
            $scope.slideError = true;
            $scope.slideMessage = message;
        },
        success: function(message) {
            $scope.slideShow = true;
            $scope.slideSuccess = true;
            $scope.slideMessage = message;
        }
    }

    return {
       restrict: 'A',
       replace: true,
       transclude: true,
       template: '<section class="slide">' +
                '<div data-ng-class="{\'slide-show\' : slideShow, \'slide-error\' : slideError, \'slide-success\' : slideSuccess, \'slide-hide\' : slideHide}">' +
                    '<p>{{ slideMessage }}</p>' +                           
                '</div>' +
            '</section>'
            }
        }
    );

And call within my child controllers:

app.controller('Child1Ctrl', function($scope) {
    $scope.child1 = function () {

        $scope.$parent.slider.initialise();

    }
});

app.controller('Child2Ctrl', function($scope) {
    $scope.child2 = function () {

        $scope.$parent.slider.success('Display some text');

    }
});

Update with fiddle:

http://jsfiddle.net/6uub3jqx/1/

If you click on the first set of buttons, the red/green ribbon appears.

If you click on the buttons withing the child1/2 controllers, there is no action.


Solution:

See fiddle: http://jsfiddle.net/6uub3jqx/2/

Essentially the child should send:

$scope.successChild1 = function(msg) { 
    $scope.$emit('successCh1', 'Some data');
};

And the parent should receive:

$scope.$on('successCh1', function (event, data) {
    $scope.$broadcast('success', data);
});

Would rootscope be a better alternative?

John Slegers
  • 45,213
  • 22
  • 199
  • 169
Oam Psy
  • 8,555
  • 32
  • 93
  • 157

2 Answers2

0

It depends. You can either use Angular events or (IMO the better approach) a service which preserves the state, for example:

.factory('myOwnScope', function () {
    return {};
});

// include myOwnScope as dependency and share the information
// between controllers and directive by its properties
// (any Angular service is just a singleton)
Community
  • 1
  • 1
Vidul
  • 10,128
  • 2
  • 18
  • 20
  • thanks, but i am struggling to see how this fits in to the whole solution that i have shared above. – Oam Psy Jul 28 '15 at 09:13
  • Please, check these [answers](http://stackoverflow.com/questions/17470419/angularjs-shared-state-between-controllers). – Vidul Jul 28 '15 at 09:16
0

There are several ways to do this. Which way is best really depends on what your trying to achieve.

One possibility is injecting data into your directive. Then you don't need the $parent variable.

It would go something like this (but can't garantee it works because you don't have a plunker or something like that)

In your html:

<section my-directive mytext="myobject.mymessage"></section>

In your controller:

$scope.myobject = { mymessage: 'hi there' };

In your directive:

return {
   restrict: 'A',
   scope: { mytext: '=' }
   template: '{{mytext}}'
}
Sander_P
  • 1,787
  • 1
  • 13
  • 37