6

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

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

我探索了各种选择。

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

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

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

4

2 回答 2

4

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

由于服务和指令中没有可用的原型信息并且直接扩展 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

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

于 2013-10-29T00:52:10.103 回答
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();
        }
    }
}]);
于 2014-01-07T18:34:58.183 回答