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?

4 Answers 4

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).

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks, that works perfect! I'm not completely comfortable with the scope variables, but that helped clear up a lot of questions I had, including how to use them.
Now that we're passing models instead of values, I suggest model="varForward" and then scope: { model: '=' }.
@ShaiRez Is this the best way to take the array and put it in a template? I'm fairly new wondering if there are alternatives.
does this work as of 1.08 because it doesn't seem to be for me
Yep, it has not changed
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);
        }
    }
});

1 Comment

@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.
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); 

1 Comment

Thanks. I wish this was better explained in the documentation.
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)

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.