将angular.extend()用于控制器和覆盖函数

时间:2017-04-18 14:31:20

标签: javascript angularjs inheritance angular-controller

我正在使用Angular 1.4.8并尝试扩展控制器。原始控制器和扩展控制器都非常相似,但我想在扩展控制器中覆盖一个功能。

angular.module('app').controller('ControllerOne', function() {

    var vm = this;

    vm.data = {};

    vm.callSayHello = function() {
        vm.sayHello();
    }

    vm.sayHello = function() {
        console.log('Hello from ControllerOne.');
    }
});

angular.module('app').controller('ControllerTwo', ['$scope', function($scope) {

    angular.extend(vm, $controller('OrdersAddController', { $scope: $scope }));

    // I do not want to override vm.callSayHello(), so I don't redeclare that function.

    // This is what I want to override.
    vm.sayHello = function() {
        console.log('Hello from ControllerTwo.');

        // Some other extra handling.
    }
}]);

<button type="button" ng-click="ctrl.callSayHello()">Click Me</button>

看起来我可以覆盖ControllerOne中的ControllerTwo函数。但是对于这种特殊情况,我想要覆盖的函数vm.sayHello()不是直接从像点击这样的事件中调用的,而是由另一个函数vm.callSayHello()调用的。

那么当从vm.callSayHello()ControllerOne调用ControllerTwo时,会调用vm.sayHello(),但它始终会调用{{1}上的函数尽管在ControllerOne被重新宣布。

希望这是有道理的。但有没有办法覆盖ControllerTwo中的vm.sayHello()函数?

2 个答案:

答案 0 :(得分:1)

你可以这样做:

exploded_war
├── app_name
│   └── WEB-INF
│       ├── classes
│       │   └── ...
│       ├── servlet.xml
│       ├── lib
│       │   ├── ...
│       └── web.xml
└── META-INF
    └── ...

现在:

exploded_war
└── WEB-INF
    ├── classes
    │   └── ...
    ├── servlet.xml
    ├── lib
    │   ├── ...
    └── web.xml

但这不是花哨的,实际上很好的建议是 - 只是不扩展控制器......如果你有共同的功能 - 把它们用于服务或分开控制器。

答案 1 :(得分:1)

您可以使用javascript继承进行方法,

//controller 1
function ControllerOne() {
  this.data = {};
}

ControllerOne.prototype.callSayHello = function() {
  this.sayHello();
};

ControllerOne.prototype.sayHello = function() {
  console.log('Hello from ControllerOne.');
};

ControllerOne.$inject = [];

//controller 2
function ControllerTwo($scope) {

}

ControllerTwo.prototype = Object.create(ControllerOne.prototype);

ControllerTwo.constructor = ControllerTwo;

ControllerTwo.prototype.sayHello = function() {
  console.log('Hello from ControllerTwo.');
};

ControllerTwo.$inject = ['$scope'];


//angular controller
angular.module('app', [])
  .controller('ControllerOne', ControllerOne)
  .controller('ControllerTwo', ControllerTwo);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <div ng-controller="ControllerOne as ctrl">
    <button type="button" ng-click="ctrl.callSayHello()">Click Me (Ctrl 1)</button>
  </div>
  <div ng-controller="ControllerTwo as ctrl">
    <button type="button" ng-click="ctrl.callSayHello()">Click Me (Ctrl 2)</button>
  </div>
</div>