2017-04-18 54 views
0

我正在使用Angular 1.4.8,并试图扩展控制器。原始控制器和扩展控制器都非常相似,但是我想在扩展控制器中重写一个函数。使用angular.extend()控制器和覆盖功能

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> 

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

那么会发生什么情况是,当vm.callSayHello()从任一ControllerOneControllerTwo,这也叫vm.sayHello(),但尽管ControllerTwo被重新声明它总是呼吁ControllerOne函数调用。

希望这是有道理的。但有没有办法可以覆盖函数ControllerTwo

回答

1

,你可以做这样的:

function mySmth(vm, $scope) { 
    // no vm = this 
vm.smth = ... 
} 
现在

function baseCtrl($scope) { 
    var vm = this; 
    mySmth(vm, $scope); 
} 

function etendedCtrl($scope) { 
    var vm = this; 
    mySmth(vm, $scope); 
    vm.smth = ...// something new 
} 

但这并不花哨,实际上很好的建议是 - 只是不延长控制器......如果你有共同的功能 - 将它们提供服务或分离控制器。

+0

谢谢您的回答。我已经读过,人们通常不会推荐扩展控制器,但它们的功能非常接近,以至于我希望有一种可接受的方式。 – kenshin9

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>

+0

不错的一个。我希望在这里看到这个答案。 – Martin