3

Hi All i have a problem with my directive, i searched in the forum for any solution but i didn't found anything good for me.

I have a directive, in my html inside a ng-repeat and looks like this

<custom-slide item="{{slides[$index]}}" pos='$index'  ></custom-slide>

I need to pass item this way beacause I need to watch if the value of this object changed in my main controller.

My directive scope is like this:

 return {
restrict: 'E',
link: linker,
scope:{
    item: '@item',
    pos: '=pos'
    //slide: '@slide',

}

my problem it if when i use scope.item what i get is a string and not an objetc.

{type:0, isSelected:'slide' ,param1:'',param2:' ',param3:' '}

But i get this as string,it's any way to have this as an object, without need to parse

any advice!!? thank you very much!

EDIT

i need to have item as an object because in my linker i change de template of the directive and,in this template i have somethings like:

   <div>
   <div class="mainText">{{scope.item.param1}}</div>
   <div class="footer Text">{{scope.item.param2}}</div>
   </div>

so when {{scope.item.param1 }} is evaluated the value is undefined, because isn't an object

Pablo Ortuño
  • 169
  • 2
  • 9

3 Answers3

0

Try removing the {{}} from the item attr:

<custom-slide item="slides[$index]" pos="$index"></custom-slide>
  • i'm still having a string, in this case my item = "slides[$index]" .. I need to operate with {{}} to have the value of the expresion, but get the value as an object not as a string – Pablo Ortuño Dec 17 '14 at 20:29
  • Hm... well, you can try to JSON.parse() the string back to a object, if i find the answer to why you're getting a string i will post it here – Tadeu Rahian Dec 17 '14 at 20:31
  • http://stackoverflow.com/questions/14050195/what-is-the-difference-between-and-in-directive-scope – Tadeu Rahian Dec 17 '14 at 20:33
  • Try using: "item: '=item'" instead of using "item: '@item'" – Tadeu Rahian Dec 17 '14 at 20:33
  • yes, thats an option but, because of my code inside the linker, I need to get the item directly as an obj! =(, the option =item didnt work with {{}} – Pablo Ortuño Dec 17 '14 at 20:35
  • i think using your link, my solution is: "With @, you will need to use attr.$observe('title', function(value) { ... }) if you need to use the value in your link(ing) function" isn't it? so in my code i use: scope.$watch('item', function(newValue) { } }); but newvalue is a string! – Pablo Ortuño Dec 17 '14 at 20:44
0

You should use = if you are trying to bind an expression:

 return {
restrict: 'E',
link: linker,
scope:{
    item: '=',
    pos: '=pos'
    //slide: '@slide',

}

Then pass the expression in the attribute without the braces:

<custom-slide item="slides[$index]" pos="$index" ></custom-slide>
Ufuk Hacıoğulları
  • 37,978
  • 12
  • 114
  • 156
  • oki ,thats makes item be an obj but $watch doesn't work, i think maybe because scope.item is an internal variable of the directive and don't update when slides[index] is updated in the controller – Pablo Ortuño Dec 17 '14 at 21:08
  • I think it should. Maybe you need to pass object equality checking. [Docs](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch) – Ufuk Hacıoğulları Dec 17 '14 at 21:13
  • mmm not for me, i understand the = as a way to copy the value inside the directive scope, so if it change outside , the scope does not know, and the "@" as a way to pass the reference! maybe i'm wrong, but with "=" when i update the controller $scope.slide, inside the directive this change is not visible – Pablo Ortuño Dec 17 '14 at 21:19
  • 1
    Use $watchCollection, from inside your directive. – Dylan Dec 17 '14 at 21:19
0

You are getting a string because you are literally placing the JSON in to the DOM, which is a very bad idea and removes your ability to modify by reference.

Basically you cannot pass the JSON as an attribute, in fact there is no reason to. Here is a version of your directive that will only pass 'how' you get at the data from the scope and the use $parse to actually get that data.

HTML

<custom-slide item="slides[$index]}.item}" pos='$index'  ></custom-slide>

Directive

module.directive('customSlide', function($parse) {
    return {
        restrict: 'E',
        link: function(scope, element, attrs) {
            var pos = attrs.pos;
            var item = $parse(attrs.item)(scope);
        }
    }
});
Enzey
  • 5,254
  • 1
  • 18
  • 20