最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Curly braces in directive attribute, angularJS - Stack Overflow

programmeradmin0浏览0评论

I have a directive which uses the id parameter to get an array in the controller's scope, which works fine if the id is static value, however if I use curly braces (for example I repeat the directive using ng-repeat and so each id needs to be unique, though if I use another attribute than id it still doesn't work), then it doesn't work, the curly braces are not evaluated, and looking at the source in the web inspector, it is literally id={{index}} rather than id=1.

EDIT: What I'm trying to do is when there is a stack element in the html, it creates a variable in the current scope (not the directive's scope) with the same name as the id.

app.directive('stack', function() {
    return {
        restrict: 'E',
        templateUrl: 'stack.html',
        scope: {
            cards: '=id',
            name: '@id',
            countOnly: '@'
        },
        link: function(scope) {
            scope.cards = [];
            //because of cards: '=id', scope.cards is bound to the parentscope.<value of id attr>, so setting scope.cards to [], also creates the variable in the parent scope.
        }
    };
});

The stack.html template simply contains (at the moment it will be expanded later):

<div class="stack">The stack called {{name}} contains {{cards.length}} cards</div>

So if I have this in my index.html:

<stack id="deck"></stack>
<span>There are {{deck.length}} cards in deck</span>

The result is:

The stack called deck contains 0 cards
There are 0 cards in deck

(and if I were to add a card to the deck array, then both zeros would change to one)


The above works, as it doesn't use ng-repeat, the attributes are hardcoded. Below the attributes need to be dynamic, and this doesn't work as the curly braces are not evaluated.

However if I want to have multiple decks by using ng-repeat it doesn't work:

<stack ng-repeat="index in range(5)" id="slot{{index}}"></stack>

then the id remains literally "slot{{index}}", not "slot0", etc.

I could do:

<stack id="slot0"></stack>
<stack id="slot1"></stack>
<stack id="slot2"></stack>
<stack id="slot3"></stack>
<stack id="slot4"></stack>

and it would work as I expect.

It's almost like I need the cards: '=id', to be cards: '=$parse(id)', (or maybe only parse if it contains braces)

I have a directive which uses the id parameter to get an array in the controller's scope, which works fine if the id is static value, however if I use curly braces (for example I repeat the directive using ng-repeat and so each id needs to be unique, though if I use another attribute than id it still doesn't work), then it doesn't work, the curly braces are not evaluated, and looking at the source in the web inspector, it is literally id={{index}} rather than id=1.

EDIT: What I'm trying to do is when there is a stack element in the html, it creates a variable in the current scope (not the directive's scope) with the same name as the id.

app.directive('stack', function() {
    return {
        restrict: 'E',
        templateUrl: 'stack.html',
        scope: {
            cards: '=id',
            name: '@id',
            countOnly: '@'
        },
        link: function(scope) {
            scope.cards = [];
            //because of cards: '=id', scope.cards is bound to the parentscope.<value of id attr>, so setting scope.cards to [], also creates the variable in the parent scope.
        }
    };
});

The stack.html template simply contains (at the moment it will be expanded later):

<div class="stack">The stack called {{name}} contains {{cards.length}} cards</div>

So if I have this in my index.html:

<stack id="deck"></stack>
<span>There are {{deck.length}} cards in deck</span>

The result is:

The stack called deck contains 0 cards
There are 0 cards in deck

(and if I were to add a card to the deck array, then both zeros would change to one)


The above works, as it doesn't use ng-repeat, the attributes are hardcoded. Below the attributes need to be dynamic, and this doesn't work as the curly braces are not evaluated.

However if I want to have multiple decks by using ng-repeat it doesn't work:

<stack ng-repeat="index in range(5)" id="slot{{index}}"></stack>

then the id remains literally "slot{{index}}", not "slot0", etc.

I could do:

<stack id="slot0"></stack>
<stack id="slot1"></stack>
<stack id="slot2"></stack>
<stack id="slot3"></stack>
<stack id="slot4"></stack>

and it would work as I expect.

It's almost like I need the cards: '=id', to be cards: '=$parse(id)', (or maybe only parse if it contains braces)

Share Improve this question edited Sep 13, 2014 at 11:39 Jonathan. asked Sep 12, 2014 at 20:49 Jonathan.Jonathan. 55.6k55 gold badges197 silver badges300 bronze badges 6
  • You mentioned in one of your ments that range function returns ["slot1", "slot2",...] but in your statement above it mentions that it returns a series of numbers? so which is it? – ryeballar Commented Sep 13, 2014 at 0:24
  • It is numbers, but in my ment I said "say the range function returns...", as in for that ment it's more convienient. – Jonathan. Commented Sep 13, 2014 at 1:15
  • hmm let me get this straight, you want scope.cards as the reference for the returned array of the range() function while you want scope.name to be the item of that array? – ryeballar Commented Sep 13, 2014 at 1:28
  • can you please post your controller code as well, where did you get "The stack called deck contains 0 cards", the {{name}} = "deck"? – ryeballar Commented Sep 13, 2014 at 4:29
  • The name is gotten from the id, by the line in the scope object in the directive – Jonathan. Commented Sep 13, 2014 at 11:02
 |  Show 1 more ment

2 Answers 2

Reset to default 7

please see here http://jsfiddle/4su41a8e/2/

  • curly braces for one way binding
  • no braces for two way binding

HTML:

<div ng-app="app">
    <div ng-controller="firstCtrl">
        <stack ng-repeat="card in range" item="card" name="{{card.name}}"></stack>
    </div>
</div>

DIRECTIVE:

app.directive('stack', function () {
    return {
        restrict: 'AE',
        template: '<h2>cards id: {{cards.id}} </h2><p>name:{{name}}</p>',
        scope: {
            cards: '=item',
            name: '@name',
            countOnly: '@'
        }
    };
});

Inside the ng-repeat use:

<stack id="index"></stack>

You don't want the interpolated value, but the reference to the value.

In the directive, you then use data-binding (on that note you can use = or @) to bind the index to the cards variable. You now have the actual index value in the link function, accessible through cards.

Here a snippet that contains your exact problem, http://jsbin./iMezAFa/2/edit.

发布评论

评论列表(0)

  1. 暂无评论