【问题标题】:Inheriting AngularJS directives to create reusable components继承 AngularJS 指令以创建可重用组件
【发布时间】:2013-09-24 02:55:00
【问题描述】:

我已经在 AngularJS 上工作了一段时间并且研究了很多。我正在使用 AngularJS 指令构建可重用的自定义组件/小部件。我在这方面相当成功。但是,我想在做同样的事情时坚持继承。 让我用一个例子来解释。

我创建了一个指令myButton,它创建了一个具有所有样式和功能的按钮。现在我想扩展/继承这个myButton 来创建一个具有一些附加特性和功能的myToggleButton。我不想再次重写myButton 功能。

我已经探索了各种选择。

  1. 按照https://gist.github.com/BrainCrumbz/5832057 中的建议,我创建了一个工厂/服务并将其注入到指令中。但这不允许我充分利用遗产。我仍然需要重写大部分属性。

  2. 我尝试使用普通的面向对象的 JavaScript 进行继承,但在这种情况下,我不会使用 AngulrJS 指令。我想严格遵循 Angular 的概念。

因此,任何建议都将受到欢迎。

【问题讨论】:

    标签: angularjs inheritance components directive


    【解决方案1】:

    我还发现大多数继承示例都不太理想,但我提出了一个我认为干净且允许完全继承的解决方案。

    由于服务和指令中没有可用的原型信息,并且直接扩展 Object 并不好,您需要创建一个可以包含常量或非常简单的通用逻辑的高级基类。

    var BaseService = function() {};
    BaseService.prototype.toast = "french";
    BaseService.prototype.halloween = "scary";
    

    接下来让我们创建一个可以扩展的抽象服​​务(指令的逻辑相同)。

    module.factory('AbstractDirective', function(
        $http, $q, $rootScope, $compile, $timeout) {
        $.extend(this, new BaseService);
    
        // Additional logic and methods should be appended onto 'this'
        this.doStuff = function() {
            alert("abstract function called");
        };
    
        this.halloween = 'fun';
        // If adding a variable to the prototype of this extended class is desired
        //     then this function would need to be extracted to its own variable
        //     where the prototype values can be set before the function
        //     is passed to the factory. 
    
        return this;
    }
    

    现在让我们创建一个实际的实现:

    module.directive('DirectiveImpl', ['AbstractDirective', function(AbstractDirective) {
        $.extend(this, AbstractDirective);
        // A great part about this implementation pattern is that
        //   DirectiveImpl does not need to pass anything to construct AbstractDirective.
        // Meaning changes to AbstractDirective will have less impacts
        //   on implementing classes.
    
        this.doStuff = function () {
            // Call
            AbstractDirective.doStuff();
            // Implement some logic additional
            alert(this.toast + "Toast\nHalloween is " + this.halloween );
        }
    
        return this;
    }]);
    

    供服务使用

    module.factory
    

    而不是

    module.directive
    

    当 DirectiveImpl 调用 doStuff 函数时,您将收到 2 个警报:

    abstract function called
    

    然后

    French Toast
    Halloween is fun
    

    可以遵循类似的模式来允许控制器完全继承,但还有更多的工作要做。

    【讨论】:

      【解决方案2】:

      我使用这个实现(基于 Enzey 的模型)让我的指令按预期工作。

      module.directive('DirectiveImpl', ['AbstractDirective', function(AbstractDirective) {
          return {
              controller: ['$scope','$element', function( $scope, $element ) {
                  $.extend($scope, AbstractDirective);
                  // A great part about this implementation pattern is that
                  //   DirectiveImpl does not need to pass anything to construct 
                  //   AbstractDirective.
                  // Meaning changes to AbstractDirective will have less impacts
                  //   on implementing classes.
      
                  $scope.doStuff = function () {
                      // Call
                      AbstractDirective.doStuff();
      
                      // Implement some logic additional
                      alert($scope.toast + "Toast\nHalloween is " + $scope.halloween );
                  } 
              },
              link: function( scope, element, opts ) {
                  scope.doStuff();
              }
          }
      }]);
      

      【讨论】:

      • 想要这个相同的选项。谢谢
      猜你喜欢
      • 1970-01-01
      • 2013-10-10
      • 2015-02-04
      • 2013-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多