6

How do you create a 2 way binding with a nested property in an isolate scope with dotted notation. I thought 'myObject.data': "=data" would work, but it does not. I don't want to link everything in the myObject object. I know I could do some sort of watch, but 'myObject.data' seems cleaner.

.directive("myDirective", [function() {
    return {
        restrict: "E",
        scope: {
            'myObject.data': "=data"
        },
        link: function (scope, element, attrs) {

            scope.myObject = {
                 data: "myValue"
            };
        }
     };
 }])

2 Answers 2

8

Isolated scopes are generally useful only with templates, they should not be used as a way to declare how you want your directive attributes to be interpreted. This is because most directives that don't have a template usually need the semantics of either a child scope or the direct scope of their environment.

In your case, you probably don't even need a $watch, because object references are what enable 2 way data binding, but without your full code I cannot be sure.

In case you want to know the translations for an isolated scope semantics to just a normal one:

@name -> attrs.name
=name -> $scope.$eval(attrs.name);
&name -> function() { return $scope.$eval(attrs.name); } 

EDIT 2:

After your comment, I came up with this plunker. To preserve two way data binding you have to use a "." in your ng-model declaration. This is because two way data binding does not work for value types, since they are immutable. You can't change the value of 100 for example. You need to pass around a reference type object and hang the values you are changing off of it. Your desire to specify the full path to the value in the isolated scope definition is not possible based on the principles that two way data binding is made possible by.

Javascript:

angular.module('plunker', [])

.directive('twoWay', function() {
  return {
    restrict: 'E',
    template: '<div><input ng-model="thing.name" type="text" /></div>',
    scope: {
      thing: "="
    }, 
    link: function(scope, element, attrs) {
    }
  };
})

.controller('MainCtrl', function($scope) {
  $scope.data = {
    name: "World"
  };
});

HTML:

  <body ng-controller="MainCtrl">
    <p>Hello {{data.name}}!</p>
    <two-way thing="data"></two-way>
  </body>
Sign up to request clarification or add additional context in comments.

7 Comments

The directive has a template with an input element. <input ng-model="myObject.data" ... >. How would you create a 2-way binding with the parent scope with the model of this input element being that it uses dotted notation. I need to keep the isolate scope on the directive.
@user1273184 your comment does not explain why you need an isolate scope. You should put the template and the reasoning behind your approach into the question.
@user1273184 I've added additional clarification on why your approach to declaring an isolated scope will not work.
The directive has a lot of code in it. It would just muddy things up. I really am just interested in using dot notation in the declaration of the isolate scope property. Something like this 'myObject.data': "=data". But this does not work. "myObject" has a lot of other properties that do not need to be exposed to the parent scope. I just want myObject.data to be exposed. I know I can work around this, but it just seems cleaner if I can do it the way I have described.
@user1273184 If myObject.data is a value type, then it is not possible to accomplish what you want with angular. You have to use the extra "." in your template ng-model declaration.
|
0

What I use in these cases is the following:

.directive("myDirective", [function() {
    return {
        restrict: "E",
        scope: {
            data: "="
        },
        controller: function($scope){
           $scope.dot = $scope //<--- here is the trick
        } 
     };
 }])

Then you can always change data in the directive's scope from an inherited scope through dot.data = 'whatever' without setting watchers.

Not very elegant but it works jsut fine in cases where you are not using the controller as syntax and don't want a $parent nightmare.

Comments

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.