【问题标题】:AngularJS : use a variable into <div>AngularJS:在 <div> 中使用变量
【发布时间】:2014-12-17 08:34:28
【问题描述】:

我有一个名为“HomeCtrl”的控制器,它计算用户总数到{{total}}绑定变量中,如下所示:

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

在我看来,我试图通过将{{total}} 作为&lt;div&gt; 标记上的属性值传递来在动画小部件中显示我的总数,如下所示:

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

这是小部件指令:

.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();
                });
            }
        };
    })

我可以在我的视图中显示正确的 {{total}} 值,但是当我将{{total}} 传递给属性时,如data-to= "{{total}}",它不起作用。它不会将其识别为数字。

【问题讨论】:

  • 在我看来,这一行
  • 我试过了:data-to= "{{total}}" data-to= {{total}} data-to= "total" data-to= total .. 没有成功!跨度>
  • 在浏览器控制台中我有这个错误:“countUp error: startVal or endVal is not a number”
  • startVal 和 endVal 是 Joignable.js 在我的代码中的变量是 data-from="1" data-to="{{total}}"
  • 查看支持网站(搜索 xe-counter)link

标签: javascript jquery angularjs data-binding angularjs-scope


【解决方案1】:

这对我有用: 控制器加载时使用异步 Web 服务调用检索数字。 这意味着调用 sm.fullyEnteredViewport 函数时该值不存在。 但幸运的是,您可以在 xe-counter 元素上设置 data-delay 属性。

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

然后像这样修改你的指令: 从元素中检索延迟值并将其余代码放入延迟函数中,如下所示:

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();
            });
        }
    };
}).
您的网络服务应在延迟时间内返回。 这对我有用。

【讨论】:

    【解决方案2】:

    你必须区分,因为如果你只是在你的指令模板中使用 {{total}} 它可以工作,因为如果在本地控制器中找不到总,Angular 会自动在父控制器中查找。

    另一方面,如果你想在一个孤立的范围内使用total的值,你可以绑定到你的data-to属性,这是通过以下代码实现的:

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

    顺便说一句。我将限制从 EAC 更改为 EA,否则您的指令将被应用两次并中断。而且你必须在属性值周围加上星号。

    查看完整的工作示例here

    【讨论】:

    • 你能告诉我我的原始指令应该如何区分'to'变量吗?
    • 我不知道您打算在哪里使用总变量,但我更新了 jsfiddle 。还是少了一些东西,因为不知道你的scrollMonitor之类的对象是从哪里来的……看部分to = scope.to
    • 谢谢,顺便说一句,它向我显示了总计的初始值,即 0 而不是更新后的总计,您知道如何获取我的 {{total}} 的最后一个值吗?非常感谢
    • console.log(scope.to); ===> 0 但在我的控制器中我做了类似的事情 $scope.total= $scope.compteur; $scope.compteur 是用户数
    • 有不同的可能性,一个是在这个jsfiddle。我这里做的基本的事情,就是把data-to="{{total}}"的属性改成data-to=total,把指令中的@换成=,并在指令的link中添加了一个watch函数。
    【解决方案3】:

    这对我有用。

    替换你的指令:

    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();
                });
            }
        };
    }).
    

    HTML 应该是这样的:

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

    请确保声明了 $scope.total 变量并且它的值是一个数字。

    【讨论】:

      猜你喜欢
      相关资源
      最近更新 更多
      热门标签