7

I have an object that I want watched inside a directive.
The directive has isolated scope and the object comes from a parent controller.

DOM:
<div hello-directive obj-to-track="{{myObj}}"></div>

Directive JS:

scope:{
   objToTrack:'@'
},
link:function(scope,element,attrs){
   scope.$watch(function(newValue){
      //Inside here, newValue is a JSON string
      //So is scope.objToTrack
   });
}

Is there anyway to get an actual object from the parent controller besides JSON.parse()
Thanks.

Francisc
  • 77,430
  • 63
  • 180
  • 276
  • 1
    you seem to be getting confused between object and JSON. JSON is a data delivery string format. Inside your app you are dealing with objects and arrays derived from that data that was delivered – charlietfl Dec 10 '13 at 23:03
  • Not sure why you think I'm confused. – Francisc Dec 10 '13 at 23:29
  • ok...explain comment `Inside here, newValue is a JSON string`. That doesn't make much sense to read – charlietfl Dec 10 '13 at 23:32
  • It means `newValue` is a valid JSON string, not sure what's unclear, sorry. – Francisc Dec 11 '13 at 00:04
  • again that makes no sense unless your application is dealing with displaying JSON as code and scope properties contain strings of JSON – charlietfl Dec 11 '13 at 00:15
  • I am asking because this question is in the context of Angular and it's what Angular does when using `@` with objects, it passes them to the directive scope as JSON strings. It's not what I want, it's what happens. – Francisc Dec 11 '13 at 01:34
  • no...`@` passes the literal value of the attribute. I see your issue now...if you want object refernce you use `=` in directive scope. Looking at comment below...you can always watch the object, and make a copy if it changes....and use copy in markup....`angular.copy()` – charlietfl Dec 11 '13 at 01:51
  • `@` converts the Object to JSON string. Thanks. – Francisc Dec 11 '13 at 10:31

1 Answers1

8

Just use the "=" binding:

scope:{
    objToTrack: "="
}

Watch it as usual:

scope.$watch("objToTrack", function(newval, oldval) {
    ...
});

Use it as:

<div hello-directive obj-to-track="myObj"></div>
Nikos Paraskevopoulos
  • 39,514
  • 12
  • 85
  • 90
  • 3
    I know, but that enables two-way binding. It's not a *huge* issue, but I'd rather not let the directive be able to write to it if possible. If it's not possible, then it will have to do. – Francisc Dec 10 '13 at 23:31
  • You cannot disallow writting - unless `myObj` is a "primitive" value. I mean even if you pass a copy of the reference to `myObj`, the directive still has access to the actual members of `myObj`. It could be done if you `angular.copy()`-ied the object before passing it to the directive, possibly in combination with the `"&"` binding, but this is probably more cumbersome. – Nikos Paraskevopoulos Dec 11 '13 at 08:12
  • 1
    I was having the same requirement and bumped into this question. I could'nt understand what @NikosParaskevopoulos says, then found this great explanation which answered the question, http://stackoverflow.com/a/14049482 – Annapoorni D Feb 25 '14 at 08:51