一次性绑定到自定义属性指令

时间:2015-12-30 11:31:50

标签: angularjs angularjs-directive binding

我正在使用基于特定属性(relative)的自定义指令的角度一次性绑定

这是我的指示:

app.directive('relative', ['$timeout', '$filter', '$compile', function ($timeout, $filter, $compile) {
    var dateFilter = $filter('date');

    return {
        restrict: 'A',
        scope: {
            datetime: '@'
        },
        link: function ($scope, $element, $attributes) {
            var timeout;

            $scope.$watch('datetime', function (dateString) {
                $timeout.cancel(timeout);

                var date = (dateString || $element.text()) * 1000;
                if (!date) return;
                date = new Date(date);
                if (!date) return;

                function update() {
                    var reference = new Date();
                    $element.text(prettyDate(date));

                    //Calculate the next update
                    var diff = Math.abs(date - reference) / 1000;
                    var delta;
                    if (diff < 45) {
                        delta = 45 - diff;
                    } else if (diff < 90) {
                        delta = 90 - diff;
                    } else if (diff < 45 * 60) {
                        delta = 60 - (diff + 30e3) % 60;
                    } else {
                        delta = 3660 - diff % 3600;
                    }

                    timeout = $timeout(update, delta * 1000);
                }

                update();    

                $element.on('$destroy', function () {
                    $timeout.cancel(timeout);
                });
            });
        }
    };
}]);

这就是我使用它的方式:

 <time relative datetime="{{ notice.date }}"></time>

或者:

 <time relative datetime="{{ ::notice.date }}"></time>

问题是:如果使用一次性绑定,如果值永远不会改变,我怎么能避免为datetime属性创建监视?角度是否会自动完成?

2 个答案:

答案 0 :(得分:0)

我认为this是您正在寻找的解决方案。

您可以通过属性获取日期时间值,而不是通过范围对象接受它。这样可以避免产生不需要的手表。无论如何,你不希望这个价值被改变,所以它真的不会产生太大的影响。

答案 1 :(得分:0)

我相信您最初使用$watch来触发update功能。您应该避免使用观察者,并选择重构观察者之外的初始化。为了避免在角度将监视变量添加到监视列表时的初始触发,您可以执行此操作(source):

$scope.$watch('datetime', function (dateString, oldDateString) {
    // notice the use of strict equality operator '==='
    // angular ensures this will only be true on the initialization of the watcher
    if (dateString === oldDateString) {
        return;
    }
});

使用<time relative datetime="{{ ::notice.date }}"></time> angular不会在一次绑定后触发观察者。

在检查$$watchers对象上的Scope属性后,我看不出有$watch注册的观察者数量有任何差异,我怀疑batarang正在使用

在回答您的问题时,我认为不可能避免使用一次性绑定创建观察者。