Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Isolate Scope "=" binding and doted notation AngularJS

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"
            };
        }
     };
 }])
like image 898
Warren Avatar asked Jan 12 '14 05:01

Warren


1 Answers

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>
like image 149
mortalapeman Avatar answered Oct 26 '22 01:10

mortalapeman