2017-04-18 23 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