【问题标题】:Custom Angular Directive, console logs, DOM updates, screen does not自定义 Angular 指令、控制台日志、DOM 更新、屏幕不
【发布时间】:2015-03-12 23:18:51
【问题描述】:

我已经使用 AngularJS 大约 6 个月了。我对此非常满意,但就像每个框架一样,都有一些“陷阱”。我的是屏幕更新。水平设置这个问题;我已经了解了所有基础知识,$apply、$apply 包含在 $timeout 中等等。即使是“嵌入”,也没有任何改变行为。

我一直在使用 Bootstrap CSS 类创建一个“进度条”,并将 AngularJS 作为我的应用程序框架。

我知道,Angular-Bootstrap (ui.bootstrap) 已经这样做了,但它表现出类似的行为,所以我想自己探索这个问题。)

这里是 $timeout 版本的代码:

(function(angular, undefined){
    function progressTracker(){
        this.message = "Loading";
        this.current = 0;
        this.percent = 0;
        this.max = 100;
    }

    progressTracker.prototype.update = function (msg, max){
        if(this.current === 0 && !!max){
            this.max = max;
        }

        this.current++;
        this.percent = Math.ceil((this.current / this.max) * 100);  
        this.message = (msg || "") + " (" + this.percent + "%)";    
    };

    angular.module("myMod",[])

        .directive("noProgressbar", ['$timeout', function($timeout){

            var directive =  {
                restrict: "A",      
                link: function(scope, el, attr, ctrl){
                    function update(){
                        var p = el.children();
                        p.css("width", this.percent + "%");
                        p.attr("aria-valuenow", this.percent);
                        p.text(this.message);                                           
                    }

                    scope[attr.noProgressbar] = new progressTracker();

                    el.addClass("progress");
                    el.append('<div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"/>');

                    scope.$watch(attr.noProgressbar + ".percent", function(newData, oldData, scope){
                        if(newData){        
                            $timeout(function(){scope.$root.$apply(update.bind(this))}.bind(this),10);                              
                        }
                    }.bind(scope[attr.noProgressbar]))

                }
            }
            return directive;
        }])         
})(angular);

这里是 HTML;自定义属性 no-progressbar 是我的 Angular 指令。 testProgress 是我存储自定义进度跟踪对象的属性的名称。请注意,此片段是在测试运行后捕获的。 CSS 样式的“宽度”在测试过程中会发生多次变化。

<div no-progressbar="testProgress" class="progress">        
    <div class="progress-bar" 
         role="progressbar" 
         aria-valuenow="100" 
         aria-valuemin="0" 
         aria-valuemax="100" style="width: 100%;">(100%)</div>
</div> 

问题:

虽然我可以在调试器 (Chrome) 中看到进度更新;我看到 DOM 正在更新(再次使用 Chrome 调试器),我可以设置断点或输出到控制台并查看预期的进度。但是,在我调整显示大小之前,屏幕根本不会更新。然后,文本消息不断更新,但 CSS 更改直到我一次又一次地调整显示大小才反映。

这对我来说似乎很奇怪,有没有其他人经历过这种行为,有解决方案,或者发现我的代码有缺陷?

【问题讨论】:

  • 我们可以找个小提琴 /plunker 来说明问题吗?
  • 让我把它放在一起。这是来自一个更大项目的 sn-p。然而,老实说,这就是代码的全部内容。
  • 在没有深入检查您的代码的情况下,我多次遇到同样的问题,主要问题是 jQuery 比 Angular 慢,这导致 DOM 操作出现一些问题。
  • @DonJuwe 在我的示例中我没有使用 jQuery,只是使用了 AngularJS。我在实际应用程序中使用 jQuery,因为它还包括 Kendo UI。但是,我得到了相同的结果。今天早上我将发布 JSBIN。
  • AngularJS中也默认包含一个轻量版的jQu​​ery。

标签: javascript css angularjs twitter-bootstrap


【解决方案1】:

更新

所以在创建 Plunker 与该线程共享时,我发现问题在开发环境之外不存在。一旦我看到这个,我意识到这一定与我在 Chrome 浏览器中使用 Bootstrap 和 AngularJS 时遇到的另一个问题有关。为简洁起见,这里有一个指向 Git 上该线程的链接。

Form Controls take as much as 10 seconds to receive focus or update border css #15814

简而言之,Chrome 存在一个错误,并且在某些非常特定的条件下会动态更新 CSS。一旦我从等式中删除了我的正常开发环境,一切正常。

我想这与“它适用于我的机器难题!”相反!

对于那些需要这种进度控制的人来说,这是我的代码。

Progress Bar made from Bootstrap and 100% Pure AngularJS

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    • 2016-12-04
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2016-09-23
    相关资源
    最近更新 更多