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

javascript - AngularJS : use a variable into <div> - Stack Overflow

programmeradmin0浏览0评论

i have a controller named "HomeCtrl" which calculates the total number of user's into the {{total}} binding variable, like this:

.controller('HomeCtrl', function($scope, $http){
    $scope.total = 0;
});

In my view, I am trying to display my total in an animated widget by passing {{total}} as the value of an attribute on a <div> tag, like this:

<div ng-controller="HomeCtrl" ng-init="init('users')">
    <div class="xe-widget xe-counter xe-counter-green" xe-counter 
       data-count=".num" data-from="1" 
       data-to= "{{total}}" 
       data-suffix="users" data-duration="3" data-easing="true">
          <div class="xe-icon">
                  <i class="linecons-user"></i>
          </div>
          <div class="xe-label">
                  <strong class="num">1k</strong>
                  <span>Users Total </span>
          </div>
   </div>            
   <center> <b> Total utilisateurs : {{total}} </b> </center>     

Here is the widget directive:

.directive('xeCounter', function(){     
        return {
            restrict: 'EAC',
            link: function(scope, el, attrs)
            {
                var $el = angular.element(el),
                    sm = scrollMonitor.create(el);
                sm.fullyEnterViewport(function()
                {
                    var opts = {
                        useEasing:      attrDefault($el, 'easing', true),
                        useGrouping:    attrDefault($el, 'grouping', true),
                        separator:      attrDefault($el, 'separator', ','),
                        decimal:        attrDefault($el, 'decimal', '.'),
                        prefix:         attrDefault($el, 'prefix', ''),
                        suffix:         attrDefault($el, 'suffix', ''),
                    },
                    $count      = attrDefault($el, 'count', 'this') == 'this' ? $el : $el.find($el.data('count')),
                    from        = attrDefault($el, 'from', 0),
                    to          = attrDefault($el, 'to', ''),
                    duration    = attrDefault($el, 'duration', 2.5),
                    delay       = attrDefault($el, 'delay', 0),
                    decimals    = new String(to).match(/\.([0-9]+)/) ? new String(to).match(/\.([0-9]+)$/)[1].length : 0,
                    counter     = new countUp($count.get(0), from, to, decimals, duration, opts);                   
                    setTimeout(function(){ counter.start(); }, delay * 1000);

                    sm.destroy();
                });
            }
        };
    })

I can display the correct value of {{total}} in my view, but when I pass {{total}} into the attribute, as data-to= "{{total}}", it does not work. It doesn't recognize it as a number.

i have a controller named "HomeCtrl" which calculates the total number of user's into the {{total}} binding variable, like this:

.controller('HomeCtrl', function($scope, $http){
    $scope.total = 0;
});

In my view, I am trying to display my total in an animated widget by passing {{total}} as the value of an attribute on a <div> tag, like this:

<div ng-controller="HomeCtrl" ng-init="init('users')">
    <div class="xe-widget xe-counter xe-counter-green" xe-counter 
       data-count=".num" data-from="1" 
       data-to= "{{total}}" 
       data-suffix="users" data-duration="3" data-easing="true">
          <div class="xe-icon">
                  <i class="linecons-user"></i>
          </div>
          <div class="xe-label">
                  <strong class="num">1k</strong>
                  <span>Users Total </span>
          </div>
   </div>            
   <center> <b> Total utilisateurs : {{total}} </b> </center>     

Here is the widget directive:

.directive('xeCounter', function(){     
        return {
            restrict: 'EAC',
            link: function(scope, el, attrs)
            {
                var $el = angular.element(el),
                    sm = scrollMonitor.create(el);
                sm.fullyEnterViewport(function()
                {
                    var opts = {
                        useEasing:      attrDefault($el, 'easing', true),
                        useGrouping:    attrDefault($el, 'grouping', true),
                        separator:      attrDefault($el, 'separator', ','),
                        decimal:        attrDefault($el, 'decimal', '.'),
                        prefix:         attrDefault($el, 'prefix', ''),
                        suffix:         attrDefault($el, 'suffix', ''),
                    },
                    $count      = attrDefault($el, 'count', 'this') == 'this' ? $el : $el.find($el.data('count')),
                    from        = attrDefault($el, 'from', 0),
                    to          = attrDefault($el, 'to', ''),
                    duration    = attrDefault($el, 'duration', 2.5),
                    delay       = attrDefault($el, 'delay', 0),
                    decimals    = new String(to).match(/\.([0-9]+)/) ? new String(to).match(/\.([0-9]+)$/)[1].length : 0,
                    counter     = new countUp($count.get(0), from, to, decimals, duration, opts);                   
                    setTimeout(function(){ counter.start(); }, delay * 1000);

                    sm.destroy();
                });
            }
        };
    })

I can display the correct value of {{total}} in my view, but when I pass {{total}} into the attribute, as data-to= "{{total}}", it does not work. It doesn't recognize it as a number.

Share Improve this question edited Dec 17, 2014 at 9:18 Reid Spencer 2,78530 silver badges37 bronze badges asked Dec 17, 2014 at 8:34 Alaa-GIAlaa-GI 4101 gold badge5 silver badges19 bronze badges 5
  • in my view , this line <div class="xe-widget xe-counter xe-counter-green" xe-counter data-count=".num" data-from="1" data-to= "{{total}}" data-suffix="users" data-duration="3" data-easing="true"> – Alaa-GI Commented Dec 17, 2014 at 8:47
  • I tried : data-to= "{{total}}" data-to= {{total}} data-to= "total" data-to= total .. no succes ! – Alaa-GI Commented Dec 17, 2014 at 9:03
  • In the browser consol i have this error : "countUp error: startVal or endVal is not a number" – Alaa-GI Commented Dec 17, 2014 at 9:05
  • 1 startVal and endVal are variables of Joignable.js in my code are data-from="1" data-to= "{{total}}" – Alaa-GI Commented Dec 17, 2014 at 9:21
  • check out the support site (search xe-counter) link – BBaker Commented Oct 22, 2015 at 19:57
Add a ment  | 

3 Answers 3

Reset to default 4

This works for me: The Number is retrieved using a async webservice call when the controller loads. That means the value isn't there when the sm.fullyEnteredViewport function is called. But luckily you can set a data-delay attribute on the xe-counter element.

<div class="xe-widget xe-counter" xe-counter data-delay="1" data-count=".num" data-from="0" data-to="{{ total }}" data-suffix="" data-duration="5">
<div class="xe-icon"><i class="linecons-cup" /></div>
<div class="xe-label"><strong class="num">0</strong><span>TOTAL</span></div>
</div>

Then modify your directive like this: Retrieve the delay value from element and put the rest of the other code into the delayed function like this:

directive('xeCounter', function () {
    return {
        restrict: 'EAC',
        link: function (scope, el, attrs) {

            var $el = angular.element(el),
                sm = scrollMonitor.create(el);
          
                //get the delay attribute from element
                var delay = attrs.delay ? attrs.delay : 0;

            sm.fullyEnterViewport(function () {

                setTimeout(function () {
                    // get all values from element delayed and start the counter
                    var opts = {
                        useEasing: attrDefault($el, 'easing', true),
                        useGrouping: attrDefault($el, 'grouping', true),
                        separator: attrDefault($el, 'separator', ','),
                        decimal: attrDefault($el, 'decimal', '.'),
                        prefix: attrDefault($el, 'prefix', ''),
                        suffix: attrDefault($el, 'suffix', '')
                    },
                    $count = attrDefault($el, 'count', 'this') == 'this' ? $el : $el.find($el.data('count')),
                    from = attrs.from ? attrs.from : 0,
                    to = attrs.to ? attrs.to : 100,
                    duration = attrs.duration ? attrs.duration : 2.5,
                    decimals = String(to).match(/\.([0-9]+)/) ? String(to).match(/\.([0-9]+)$/)[1].length : 0,
                    counter = new countUp($count.get(0), from, to, decimals, duration, opts);
                    counter.start();
                }, delay * 1000);

                sm.destroy();
            });
        }
    };
}).
Your webservice should return within the delay time. That does the trick for me.

You have to distinguish, because if you are just using {{total}} in your directive template it works, because angular automatically will look for total in the parent controller if it is not found in the local one.

On the other hand, if you want to use the value of total in an isolated scope, you can bind to your data-to attribute, and this is achieved by following code:

app.directive('xeCounter', function(){
 return {
    restrict: 'EA',
    scope: { to: '@' },
    link: function(scope)
    {
        console.log(scope.to);
    }
 };
});

Btw. I changed the restrict from EAC to EA, because otherwise your directive is going to be applied twice and breaks. And you have to put the asterisks around the attribute value.

See the full working example here.

This works for me.

Replace yours directive for this:

directive('xeCounter', function () {
    return {
        restrict: 'EAC',
        link: function (scope, el, attrs) {

            var $el = angular.element(el),
                sm = scrollMonitor.create(el);

            sm.fullyEnterViewport(function () {
                var opts = {
                        useEasing: attrDefault($el, 'easing', true),
                        useGrouping: attrDefault($el, 'grouping', true),
                        separator: attrDefault($el, 'separator', ','),
                        decimal: attrDefault($el, 'decimal', '.'),
                        prefix: attrDefault($el, 'prefix', ''),
                        suffix: attrDefault($el, 'suffix', '')
                    },
                    $count = attrDefault($el, 'count', 'this') == 'this' ? $el : $el.find($el.data('count')),
                    from = attrs.from ? attrs.from : 0,
                    to = attrs.to ? attrs.to : 100,
                    duration = attrs.duration ? attrs.duration : 2.5,
                    delay = attrs.delay ? attrs.delay : 0,
                    decimals = String(to).match(/\.([0-9]+)/) ? String(to).match(/\.([0-9]+)$/)[1].length : 0,
                    counter = new countUp($count.get(0), from, to, decimals, duration, opts);

                setTimeout(function () {
                    counter.start();
                }, delay * 1000);

                sm.destroy();
            });
        }
    };
}).

And the HTML should stay like this:

<div class="xe-widget xe-counter" xe-counter data-count=".num" data-from="0" data-to="{{ total }}" data-suffix="" data-duration="5">
<div class="xe-icon"><i class="linecons-cup" /></div>
<div class="xe-label"><strong class="num">0</strong><span>TOTAL</span></div>
</div>

Be shure that the $scope.total variable is declared and its value is an number.

发布评论

评论列表(0)

  1. 暂无评论