32

I'm trying to get an array into a template so I can use the individuals values thereof. My problem is that the attribute turns into a string once inside my template so it's no longer accessible as {{var[0]}} and that will instead return the first character of the "string", usually "["

Here is a simplified setup of the data:

"varForward": ["100", "1"],
"varBack": ["1", "100"]

Here is a simplified portion of the HTML file that interacts with that data:

<my-customer-vars value="{{varForward}}">
    </address-numbers>
<my-customer-vars value="{{varBack}}">
    </address-numbers>

and lastly here is a portion that is SUPPOSED to replace the custom tag with my own stuff:

directive('myCustomerVars', function($compile) {
    return {
        restrict: 'E',
        scope: {
            value: "@"
        },
        template:
        '<div>'+
          '<p class="body-text">Some stuff goes here</p>'+
          '<input type="text" name="firstinput" value="{{value[0]}}"> - '+
          '<input type="text" name="secondinput" value="{{value[1]}}">'+
        '</div>',
        replace: true
    }
});

So here I am, if I try using value[0] I get [ If I try to get value[1] I get " and so on. Is there any help on using arrays inside the template of a directive?

Organiccat
  • 5,633
  • 17
  • 57
  • 104

4 Answers4

46

You need to change the "@" into "=" and to pass in the array without the {{ }}

like this:

<my-customer-vars value="varForward">
    </my-customer-vars>
<my-customer-vars value="varBack">
    </my-customer-vars>

directive:

directive('myCustomerVars', function($compile) {
    return {
        restrict: 'E',
        scope: {
            value: "="
        },
        template:
        '<div>'+
          '<p class="body-text">Some stuff goes here</p>'+
          '<input type="text" name="firstinput" value="{{value[0]}}"> - '+
          '<input type="text" name="secondinput" value="{{value[1]}}">'+
        '</div>',
        replace: true
    }
});

This is happening because every expression inside a directuve attribute defined by a @ gets evaluated as only as a string, and in the other way it gets evaluated as binding expression. (with 2 way binding, so be careful).

Bruno Toffolo
  • 1,504
  • 19
  • 24
Shai Reznik - HiRez.io
  • 8,748
  • 2
  • 33
  • 33
16

If you would prefer not creating an isolate scope in the directive (such as when creating custom validation directives) you could pass the array as:

<my-customer-vars model="varForward">

And then read the value in the linking function of the directive as:

directive('myCustomerVars', function($compile) {
    return {
        restrict: 'E',
        link: function (scope, elm, attrs, ctrl) {
            var myVars = scope[attrs.model]; // <--- took a time to figure out
            console.log(myVars);
        }
    }
});
Danita
  • 2,464
  • 4
  • 23
  • 29
  • 1
    @greg this reply is from a long time ago, I suppose about the time of Angular 1.1 or 1.2. Maybe it doesn't work anymore in newer versions. I don't use Angular anymore. – Danita Dec 29 '14 at 17:08
6

Just to add to the reply of Danita, you will have to use $eval for fetching this scope variable:

Just change

var myVars = scope[attrs.model]; 

to

var myVars = scope.$eval(attrs.model); 
bish
  • 3,381
  • 9
  • 48
  • 69
Sohan Soni
  • 1,207
  • 21
  • 35
0

Just another perspective - if the problem is just managing an array of strings in angular application I would use one of the following (or any similar):

  1. ngTagsInput
  2. angular select2 with Tags mode
  3. ngList

Unless you are practicing creating your own angular directives (then just ignore my answer)

Alexander
  • 7,484
  • 4
  • 51
  • 65