0

I have an angular app like this

Plunker

Javascript:

(function(angular, module){

    module.controller("TestController", function($scope){
        $scope.magicValue = 1;
    });

    module.directive("valueDisplay", function () {
        return {
            restrict: "A",
            template: '<span>Iso Val: </span>{{ value }}<br/><span>Iso Change: </span><input data-ng-model="value" />',
            replace: false,
            scope: { },
            link: function (scope, element, attrs) {
                var pValKey = attrs.valueDisplay;

                // Copy value from parent Scope.
                scope.value = scope.$parent[pValKey];

                scope.$parent.$watch(pValKey, function(newValue) {
                    if(angular.equals(newValue, scope.value)) {
                        // Values are the same take no action
                        return;
                    }
                    // Update Local Value
                    scope.value = newValue;
                });

                scope.$watch('value', function(newValue) {
                    if(angular.equals(newValue, scope.$parent[pValKey])) {
                        // Values are the same take no action
                        return;
                    }
                    // Update Parent Value
                    scope.$parent[pValKey] = newValue;
                });
            }
        };
    });

}(angular, angular.module("Test", [])));

HTML:

<!DOCTYPE html>
<html>

    <head>
        <script data-require="angular.js@*" data-semver="1.2.0-rc2" src="http://code.angularjs.org/1.2.0-rc.2/angular.js"></script>
        <link rel="stylesheet" href="style.css" />
        <script src="script.js"></script>
    </head>

    <body ng-app="Test">
        <div ng-controller="TestController">
            <ol>
                <li>
                    <span>Parent Val: </span>{{ magicValue }}<br/>
                    <span>Parent Change:</span><input data-ng-model="magicValue" />
                </li>
                <li data-value-display="magicValue"></li>
            </ol>
        </div>
    </body>
</html>

Ok so This works and all but I'm wondering if there is not a better way of doing this 2 way binding that I have setup here?

Keep in mind that I want Isolated Scope & that I know I can define extra Attributes and use the '=' to have 2 way data binding between parent and isolated scope I'd like something like that but where the data gets passed in to the directives attribute like I have here.

1
  • 1
    What is stopping you from using scope : {valueDisplay : '=valueDisplay'}? you don't have to set up the watches and the value is still in an attribute. It's also brittle to use $parent, since you can never be sure that the value is actually set in the parent. Commented Oct 28, 2013 at 9:56

1 Answer 1

3

You can do this much more tersely using your isolated scope.

Here is an updated plunker.

You can two-way bind the value of your directive with value: '=valueDisplay'

The = tells angular you want two-way binding:

module.directive("valueDisplay", function () {
    return {
      restrict: "A",
      template: '<span>Iso Val: </span>{{ value }}<br/><span>Iso Change: </span><input data-ng-model="value" />',
      replace: false,
      scope: { value: '=valueDisplay' },
      link: function (scope, element, attrs) {

      }
    };
  });
Sign up to request clarification or add additional context in comments.

1 Comment

Was in the middle of writing the same thing, but you nailed it. The OP really just wrote what Angular does for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.