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

javascript - Angular JS directive not updating scope variable - Stack Overflow

programmeradmin2浏览0评论

I'm trying to build a simple directive in angularJs which accepts some config options via attributes, but if the attributes are not set, I want to set default values for the attributes.

Here's how I describe my scope:

scope :  {
            classes: '@',
            progress: '@'
         }

These attribs are displayed in the view in the following way:

<div class="{{classes}}">
    <div style="width: {{progress}}%;" class="bar"></div>
</div>

In the link function, I try to set the default values in this way:

link: function(scope, el, attrs)
        {
           console.log( scope.classes, scope.progress );
           if (typeof scope.classes === 'undefined')
               scope.classes = 'progress progress-warning';

           if (typeof scope.progress === 'undefined')
               scope.progress = 99;
           console.log( scope.classes, scope.progress );
        }

Here's the console output:

undefined undefined
progress progress-warning 99

So, it appears that in the scope the value is being set correctly. However in the actual html output, the attributes are not being rendered. Here's the resulting HTML:

<div class="">
    <div class="bar" style="width: %;"></div>
</div>

However if I supply these attributes inline when calling the attribute from html, e.g:

<my-directive data-progress="60" data-classes="progress" />

then it shows up fine:

<div class="progress" data-progress="60" data-classes="progress">
    <div class="bar" style="width: 60%;"></div>
</div>

My question is, when I just call <my-directive />, why does it not set the default values of progress and classes as its supposed to, from the link function? (And despite showing in console that it did)

I'm trying to build a simple directive in angularJs which accepts some config options via attributes, but if the attributes are not set, I want to set default values for the attributes.

Here's how I describe my scope:

scope :  {
            classes: '@',
            progress: '@'
         }

These attribs are displayed in the view in the following way:

<div class="{{classes}}">
    <div style="width: {{progress}}%;" class="bar"></div>
</div>

In the link function, I try to set the default values in this way:

link: function(scope, el, attrs)
        {
           console.log( scope.classes, scope.progress );
           if (typeof scope.classes === 'undefined')
               scope.classes = 'progress progress-warning';

           if (typeof scope.progress === 'undefined')
               scope.progress = 99;
           console.log( scope.classes, scope.progress );
        }

Here's the console output:

undefined undefined
progress progress-warning 99

So, it appears that in the scope the value is being set correctly. However in the actual html output, the attributes are not being rendered. Here's the resulting HTML:

<div class="">
    <div class="bar" style="width: %;"></div>
</div>

However if I supply these attributes inline when calling the attribute from html, e.g:

<my-directive data-progress="60" data-classes="progress" />

then it shows up fine:

<div class="progress" data-progress="60" data-classes="progress">
    <div class="bar" style="width: 60%;"></div>
</div>

My question is, when I just call <my-directive />, why does it not set the default values of progress and classes as its supposed to, from the link function? (And despite showing in console that it did)

Share Improve this question asked Aug 10, 2013 at 1:24 AliAli 267k269 gold badges592 silver badges786 bronze badges 7
  • Did you try to use scope.$apply(); ? If you can, post a plunker or fiddle? – Deividi Cavarzan Commented Aug 10, 2013 at 1:48
  • you dont need to do scope.$apply() – David Chase Commented Aug 10, 2013 at 1:51
  • can you post the full directive? – David Chase Commented Aug 10, 2013 at 1:56
  • @DeividiCavarzan I get the digest already in progress if I put the code within the link function inside scope.$apply – Ali Commented Aug 10, 2013 at 2:02
  • Ok my bad, I didn't see that you are changing on the link function. – Deividi Cavarzan Commented Aug 10, 2013 at 2:05
 |  Show 2 more ments

3 Answers 3

Reset to default 4

Try this:

link: function(scope, element, attrs) {
    scope.classes = attrs.classes || 'progress progress-warning';
    scope.progress = attrs.progress || 99;
}

And you can ditch the scope : { classes: '@', progress: '@' } part of the directive.

I see you're having some hard time writing your directive. Check out this one I've implemented recently. Perhaps it'll help you wrap up yours.

Try this:

if (typeof scope.progress === 'undefined') {
       attrs.$set('progress', 99);
}

And set:

<div class="bar" style="width: {{progress}}%;"></div>

See this Plunker. It will set 99 if data-progress is not declared or if is data-progress=""

change your scope to

scope: {
  ngModel: '@'
}
发布评论

评论列表(0)

  1. 暂无评论