Aaron Beall
Aaron Beall

Reputation: 52193

Two-way binding with parent.parent scope

I have an issue where a directive with an isolate scope is not making changes via binding to its parent.parent scope.

In summary, I would expect that changes made to a property in the directive's isolate scope which is bound to a parent property would propagate all the way up parent scopes for that property (the property was inherited from a parent.parent scope to begin with), but it doesn't. It only changes the value on the immediate parent scope, while the parent.parent scope has the old value. Worse, any changes to the parent.parent scope property no longer trickle down to the isolate scope or its immediate parent. I understand this is the normal behavior of Javascript's prototype inheritance which Angular scopes are built on, but it's not wanted in this case of two-way data binding and I'm looking for a solution in Angular.

Here is an example of the behavior: http://jsfiddle.net/abeall/RmDuw/344/

My HTML contains a controller div (MyController1), in it is another controller div (MyController2), and in that is a directive (MyDirective):

<div ng-controller="MyController">
    <p>MyController1: {{myMessage}} <button ng-click="change()">change</button></p>
    <div ng-controller="MyController2">
        <p>MyController2: {{myMessage}} <button ng-click="change()">change</button></p>
        <p>MyDirective: <my-directive message="myMessage"/></p>
    </div>
</div>

The Javascript defines myMessage on the outer MyController scope, the inner MyController2 scope inherits and binds myMessage to message on the directive, and the MyDirective defines message as an isolate scope property. At each level a change() function is defined which changes the local message property:

var app = angular.module('myApp', []);

function MyController($scope) {
    var count = 0;
    $scope.myMessage = "from controller";
    $scope.change = function(){
        $scope.myMessage = "from controller one " + (++count);
    }
}

function MyController2($scope) {
    var count = 0;
    $scope.change = function(){
        $scope.myMessage = "from controller two " + (++count);
    }
}

app.directive('myDirective', function() {
    return {
        restrict: 'E',
        replace: true,
        template: '<span>Hello {{message}} <button ng-click="change()">change</button></span>',
        scope: {
            message: "="
        },
        link: function(scope, elm, attrs) {
            var count = 0;
            scope.change = function(){
                scope.message = "from directive " + (++count);
            }
        }
    };
});

What you'll notice is that:

So my question is:

Upvotes: 1

Views: 2055

Answers (2)

DWDuck
DWDuck

Reputation: 239

The easiest change is using $scope.msg.mymessage instead of just $scope.msg in your root controller.

function MyController($scope) {
    var count = 0;
    $scope.msg = {};
    $scope.msg.myMessage = "from controller";
    $scope.change = function(){
        $scope.msg.myMessage = "from controller one " + (++count);
    }
}

Here's a forked fiddle (that sounds funny) with the intended results.

http://jsfiddle.net/nk5cdrmx/

Upvotes: 0

azium
azium

Reputation: 20634

as @Claies mentioned, using controller as is a great idea. This way you can be direct about which scope you want to update, as well as easily being able to pass scopes around in methods.

Here is a fiddle of the results you were likely expecting

Syntax: ng-controller="MyController as ctrl1"

Then inside: {{ctrl1.myMessage}} or ng-click="ctrl1.change()" and click="ctrl2.change(ctrl1)"

This changes the way you write your controller by leaving out the $scope dependency unless you need it for other reasons then holding your model.

function MyController () {
  var count = 0
  this.myMessage = "from controller"
  this.change = function () {
    this.myMessage = "from controller one " + (++count)
  }
}

function MyController2 () {
  var count = 0
  this.change = function (ctrl) {
    ctrl.myMessage = "from controller two " + (++count)
  }
}

Upvotes: 1

Related Questions