扩展第三方角度指令并更改其模板

时间:2014-10-28 14:40:42

标签: javascript angularjs angularjs-directive extending angular-template

我正在使用Daniel Crisps AngularJS Range Slider https://github.com/danielcrisp/angular-rangeslider,并希望扩展他的指令并修改模板。

他的指令看起来像这样(缩短了空间):

angular.module('ui-rangeSlider', [])
.directive('rangeSlider', [
    function () {
       return {
          restrict: 'A',
          replace: true,
          template: ['<div class="ngrs-range-slider">',
                         '<div class="ngrs-runner">',
                           '<div class="ngrs-handle ngrs-handle-min"><i></i></div>',
                           '<div class="ngrs-handle ngrs-handle-max"><i></i></div>',
                           '<div class="ngrs-join"></div>',
                         '</div>',
                         '<div class="ngrs-value-runner">',
                           '<div class="ngrs-value ngrs-value-min" ng-show="showValues"><div>{{filteredModelMin}}</div></div>',
                           '<div class="ngrs-value ngrs-value-max" ng-show="showValues"><div>{{filteredModelMax}}</div></div>',
                         '</div>',
                       '</div>'].join('')
       }
    }
]);

我一直在尝试使用这个问题Extending Angular Directive中的建议,将我的指令命名为完全相同的名称(例如缩写):

angular.module('myDirective', [])
.directive('rangeSlider', [
    function () {
        return {
            restrict: 'A',
            priority: 500,
            template: ['<div></div><div></div>'].join('')
        }
    }
]);

但是我收到以下错误: 要求模板的多个指令[rangeSlider,rangeSlider]:

之前是否有人遇到此问题,如何在不修改原始模板的情况下更新原始模板?

编辑:在我的例子中有一个额外的')'。

3 个答案:

答案 0 :(得分:3)

我找到了一种方法,允许您修改第三方模板而无需触及其代码,并且AngularJS中没有任何错误。它与您的尝试有点不同,您可以使用module.config() $provide来装饰第三方模块上的指令,而不是使用相同的名称在您自己的模块上定义指令。

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.js"></script>
<script>
    // third-party code - cannot be modified
    angular.module('ui-rangeSlider', []).directive('rangeSlider', [function() {
        return {
            restrict: 'A',
            replace: true,
            template: '<div>base</div>'
        };
    }]);

    // this is your extension overriding the original template
    angular.module('ui-rangeSlider').config(['$provide', function($provide) {
        $provide.decorator('rangeSliderDirective', function($delegate) {
            var dir = $delegate[0];

            dir.template = ['<div>', dir.template, '<div>extended</div></div>'].join('');

            return $delegate;
        })
    }]);

    // this is your app
    angular.module('sample', ['ui-rangeSlider']);
</script>
<body ng-app="sample">
    <div range-slider></div>
</body>

您可以在https://jsfiddle.net/sjxwLe4k/4/现场试试。

答案 1 :(得分:2)

在一堆stackoverflow搜索如何扩展AngularJS指令(最好是版本1.5。*)后,这对我有用。

稍微修改以上示例中的装饰器和$ delegate以使用Angular 1.5.8:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>

<script>
        angular.module('ui-rangeSlider', []).directive('rangeSlider', [function() {
        return {
            restrict: 'A',
            replace: true,
            template: ['<div>base</div>'].join('')
        };
    }]);
    angular.module('myDirective', []).directive('rangeSlider', [function() {
        return {
            restrict: 'A',
            priority: 500,
            template: ['<div>extended</div>'].join('')
        }
    }]);
    angular.module('sample', ['ui-rangeSlider', 'myDirective'])
        .decorator('rangeSliderDirective', ['$delegate', function($delegate){
            console.log($delegate);
          $delegate.shift();
          return $delegate;
        }]);
</script>

<body ng-app="sample">
    <div range-slider></div>
</body>

您可以在此处看到上述代码:
https://jsfiddle.net/sjxwLe4k/6/

答案 2 :(得分:0)

看了你的例子。我可以毫无问题地运行它。我将'myDirective'和'ui-rangeSlider'添加到一个空的应用程序中,我没有任何问题。我能够从myDirective中删除模板,它显示了ui-rangeSlider模板。

HTML:

<div range-slider></div>

完整示例:

<!doctype html>
<html ng-app="sample">
  <head>
    <title>My Angular App</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
    <script>
        angular.module('sample', ['ui-rangeSlider', 'myDirective']);
        angular.module('ui-rangeSlider', [])
            .directive('rangeSlider', [
                function () {
                   return {
                      restrict: 'A',
                      replace: true,
                      template: ['<div class="ngrs-range-slider">',
                                     '<div class="ngrs-runner">',
                                       '<div class="ngrs-handle ngrs-handle-min"><i></i></div>',
                                       '<div class="ngrs-handle ngrs-handle-max"><i></i></div>',
                                       '<div class="ngrs-join"></div>',
                                     '</div>',
                                     '<div class="ngrs-value-runner">',
                                       '<div class="ngrs-value ngrs-value-min" ng-show="showValues"><div>{{filteredModelMin}}</div></div>',
                                       '<div class="ngrs-value ngrs-value-max" ng-show="showValues"><div>{{filteredModelMax}}</div></div>',
                                     '</div>',
                                   '</div>'].join('')
                   }
                }
            ]);
            angular.module('myDirective', [])
                .directive('rangeSlider', [
                    function () {
                        return {
                            restrict: 'A',
                            priority: 500,
                            template: ['<div></div>test<div></div>'].join('')
                        }
                    }
                ]);
    </script>
  </head>
  <body>
    <div range-slider></div>
  </body>
</html>