动态更新指令 (1.2 rc3)

Dynamically Updating Directive (1.2 rc3)

本文关键字:rc3 更新 指令 动态      更新时间:2023-09-26

我今天第一次玩指令,并试图构建一个可重用的进度条指令(基于 Bootstrap 3.0),我可以根据值动态填充或清空。指令定义如下:

directive('progressBar', function () {
    var success = 'progress-bar progress-bar-success';
    var warning = 'progress-bar progress-bar-warning';
    var danger = 'progress-bar progress-bar-danger';
    var setCssStyling = function (width) {
        if (width >= 50) {
            return success;
        } else if (width >= 20) {
            return warning;
        } else {
            return danger;
        }
    }
    var formatWidth = function (width) {
        return 'width: ' + width + '%';
    }
    return {
        restrict: 'E',
        scope: {},
        template: '<div class="progress progress-striped active">' +
            '<div ng-class="cssStyle" role="progressbar" style="{{ width }}"></div>' +
            '</div>',
        link: function (scope, element, attrs) {
            if (attrs.width) {
                scope.width = formatWidth(attrs.width);
            } else {
                scope.width = formatWidth(0);
            }
            scope.$watch(attrs.width, function (newVal) {
                scope.width = formatWidth(newVal);
                scope.cssStyle = setCssStyling(newVal);
            });
        }
    }
});

鉴于以下测试用法,这完全按计划工作:

<progress-bar width="100"></progress-bar>
<progress-bar width="45"></progress-bar>
<progress-bar width="15"></progress-bar>

我希望做的是能够将 width 属性动态绑定到控制器中不断变化的值,以便进度条的宽度和样式会移动。我尝试绑定到控制器中每秒更改的值:

<progress-bar width="{{ today.seconds }}"></progress-bar>

但是当我检查该进度条的范围时,宽度始终设置为 width: undefined% .有没有更好的方法来完成这样的动态更新内容,或者我在范围或愚蠢方面遗漏了一些东西?

你在attrs.width上使用scope.$watch,这意味着它不应该是插值。所以你应该简单地做<progress-bar width="today.seconds"></progress-bar>.

如果您希望能够使用插值,则可以使用 scope.$observe ,并且还需要解析宽度(因为插值将返回一个字符串)。

更新:由于您已经设置了隔离作用域(scope: {}),因此您需要在作用域哈希对象中绑定width

return {
    restrict: 'E',
    scope: { width: '='},
    template: '<div class="progress progress-striped active">' +
        '<div ng-class="cssStyle" role="progressbar" style="{{ cssWidth }}"></div>' +
        '</div>',
    link: function (scope, element, attrs) {
        scope.cssWidth = '';
        scope.$watch('width', function (newVal) {
            scope.cssWidth = formatWidth(newVal);
            scope.cssStyle = setCssStyling(newVal);
        });
    }
}

当然,您也可以放弃隔离范围,如果这在您的上下文中有意义。 您也可以cssWidth一起删除,只需在style属性中进行格式化即可。

http://plnkr.co/edit/Zx1fgHYyXuxByHH6YorP

在你的指令中,你需要使用

scope: { width: '=' }

=这种参数说到角度在你的指令范围内创建一个双向参数,所以,如果你在指令中改变它的值,你的控制器将受到影响,如果你在控制器中改变这个值,你的指令将被反映