답변:
아마도 당신은 컨트롤러를 확장하지 않습니다하지만 컨트롤러를 확장하거나 하나의 컨트롤러를 여러 컨트롤러의 믹스 인을 만드는 것이 가능하다.
module.controller('CtrlImplAdvanced', ['$scope', '$controller', function ($scope, $controller) {
// Initialize the super class and extend it.
angular.extend(this, $controller('CtrlImpl', {$scope: $scope}));
… Additional extensions to create a mixin.
}]);
상위 컨트롤러가 생성되면 그 안에 포함 된 로직도 실행됩니다. $scope
값만 전달 하면되지만 자세한 내용은 $ controller ()를 참조하십시오 . 다른 모든 값은 정상적으로 주입됩니다.
@mwarren , Angular 의존성 주입으로 문제를 자동으로 처리합니다. 필요한 경우 $ scope를 주입하기 만하면되지만 원하는 경우 다른 주입 된 값을 무시할 수 있습니다. 다음 예제를 보자.
(function(angular) {
var module = angular.module('stackoverflow.example',[]);
module.controller('simpleController', function($scope, $document) {
this.getOrigin = function() {
return $document[0].location.origin;
};
});
module.controller('complexController', function($scope, $controller) {
angular.extend(this, $controller('simpleController', {$scope: $scope}));
});
})(angular);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.js"></script>
<div ng-app="stackoverflow.example">
<div ng-controller="complexController as C">
<span><b>Origin from Controller:</b> {{C.getOrigin()}}</span>
</div>
</div>
'complexController'에 의해 생성 될 때 $ document가 'simpleController'에 전달되지 않지만 $ document가 우리에게 주입됩니다.
$.extend()
, 당신은 단순히 전화 할 수 있습니다$controller('CtrlImpl', {$scope: $scope});
angular.extend
(또는 $.extend
)을 사용하지 않는 것은 실제로 확장하는 것을 의미 $scope
하지만, 기본 컨트롤러가 일부 속성 (예 this.myVar=5
this.myVar
angular.extend
handleSubmitClick
부를 것이다 handleLogin
차례에 있던 loginSuccess
및 loginFail
. 그래서, 내 확장 된 컨트롤러에서 나는 다음에 과부하를했다 handleSubmitClick
, handleLogin
그리고 loginSucess
올바른에 대한 loginSuccess
기능을 사용할 수 있습니다.
상속을 위해 표준 JavaScript 상속 패턴을 사용할 수 있습니다. 다음은 사용하는 데모입니다$injector
function Parent($scope) {
$scope.name = 'Human';
$scope.clickParent = function() {
$scope.name = 'Clicked from base controller';
}
}
function Child($scope, $injector) {
$injector.invoke(Parent, this, {$scope: $scope});
$scope.name = 'Human Child';
$scope.clickChild = function(){
$scope.clickParent();
}
}
Child.prototype = Object.create(Parent.prototype);
controllerAs
구문 을 사용하는 경우 (내가 권장하는) 고전 상속 패턴을 사용하는 것이 훨씬 쉽습니다.
function BaseCtrl() {
this.name = 'foobar';
}
BaseCtrl.prototype.parentMethod = function () {
//body
};
function ChildCtrl() {
BaseCtrl.call(this);
this.name = 'baz';
}
ChildCtrl.prototype = Object.create(BaseCtrl.prototype);
ChildCtrl.prototype.childMethod = function () {
this.parentMethod();
//body
};
app.controller('BaseCtrl', BaseCtrl);
app.controller('ChildCtrl', ChildCtrl);
또 다른 방법은 기본 컨트롤러가되는 "추상적 인"생성자 함수를 만드는 것입니다.
function BaseController() {
this.click = function () {
//some actions here
};
}
module.controller('ChildCtrl', ['$scope', function ($scope) {
BaseController.call($scope);
$scope.anotherClick = function () {
//other actions
};
}]);
글쎄, 나는 당신이 무엇을 달성하고자하는지 확실하지 않지만 일반적으로 서비스가 갈 길입니다. Angular의 스코프 상속 특성을 사용하여 컨트롤러간에 코드를 공유 할 수도 있습니다.
<body ng-controller="ParentCtrl">
<div ng-controller="FirstChildCtrl"></div>
<div ng-controller="SecondChildCtrl"></div>
</body>
function ParentCtrl($scope) {
$scope.fx = function() {
alert("Hello World");
});
}
function FirstChildCtrl($scope) {
// $scope.fx() is available here
}
function SecondChildCtrl($scope) {
// $scope.fx() is available here
}
$scope.$parent.fx( )
가 실제로 정의 된 곳이기 때문에, 그것을 할 수있는 많은 청소기 방법이?
컨트롤러를 확장하지 않습니다. 동일한 기본 기능을 수행하는 경우 해당 기능을 서비스로 이동해야합니다. 이 서비스는 컨트롤러에 주입 할 수 있습니다.
이 기사 에서 얻은 또 다른 좋은 해결책 :
// base controller containing common functions for add/edit controllers
module.controller('Diary.BaseAddEditController', function ($scope, SomeService) {
$scope.diaryEntry = {};
$scope.saveDiaryEntry = function () {
SomeService.SaveDiaryEntry($scope.diaryEntry);
};
// add any other shared functionality here.
}])
module.controller('Diary.AddDiaryController', function ($scope, $controller) {
// instantiate base controller
$controller('Diary.BaseAddEditController', { $scope: $scope });
}])
module.controller('Diary.EditDiaryController', function ($scope, $routeParams, DiaryService, $controller) {
// instantiate base controller
$controller('Diary.BaseAddEditController', { $scope: $scope });
DiaryService.GetDiaryEntry($routeParams.id).success(function (data) {
$scope.diaryEntry = data;
});
}]);
서비스를 주입하여 서비스를 생성하고 모든 컨트롤러에서 해당 동작을 상속 할 수 있습니다.
app.service("reusableCode", function() {
var reusableCode = {};
reusableCode.commonMethod = function() {
alert('Hello, World!');
};
return reusableCode;
});
그런 다음 컨트롤러에서 위의 재사용 가능한 코드 서비스에서 확장하려고합니다.
app.controller('MainCtrl', function($scope, reusableCode) {
angular.extend($scope, reusableCode);
// now you can access all the properties of reusableCode in this $scope
$scope.commonMethod()
});
데모 플 런커 : http://plnkr.co/edit/EQtj6I0X08xprE8D0n5b?p=preview
다음과 같이 시도해 볼 수 있습니다 (테스트하지 않았습니다).
function baseController(callback){
return function($scope){
$scope.baseMethod = function(){
console.log('base method');
}
callback.apply(this, arguments);
}
}
app.controller('childController', baseController(function(){
}));
서비스 , 공장 또는 공급자로 확장 할 수 있습니다 . 그것들은 동일하지만 다른 정도의 유연성을 가지고 있습니다.
여기 팩토리를 사용하는 예 : http://jsfiddle.net/aaaflyvw/6KVtj/2/
angular.module('myApp',[])
.factory('myFactory', function() {
var myFactory = {
save: function () {
// saving ...
},
store: function () {
// storing ...
}
};
return myFactory;
})
.controller('myController', function($scope, myFactory) {
$scope.myFactory = myFactory;
myFactory.save(); // here you can use the save function
});
그리고 여기서 저장 기능을 사용할 수도 있습니다.
<div ng-controller="myController">
<input ng-blur="myFactory.store()" />
</div>
$ controller ( 'ParentController', {$ scope : $ scope})를 직접 사용할 수 있습니다
module.controller('Parent', ['$scope', function ($scope) {
//code
}])
module.controller('CtrlImplAdvanced', ['$scope', '$controller', function ($scope, $controller) {
//extend parent controller
$controller('CtrlImpl', {$scope: $scope});
}]);
일반 JavaScript 상속과 결합 된 Angular "as"구문을 사용할 수 있습니다
자세한 내용은 여기를 참조하십시오 http://blogs.microsoft.co.il/oric/2015/01/01/base-controller-angularjs/
나는 이것을하는 함수를 썼다 :
function extendController(baseController, extension) {
return [
'$scope', '$injector',
function($scope, $injector) {
$injector.invoke(baseController, this, { $scope: $scope });
$injector.invoke(extension, this, { $scope: $scope });
}
]
}
다음과 같이 사용할 수 있습니다.
function() {
var BaseController = [
'$scope', '$http', // etc.
function($scope, $http, // etc.
$scope.myFunction = function() {
//
}
// etc.
}
];
app.controller('myController',
extendController(BaseController,
['$scope', '$filter', // etc.
function($scope, $filter /* etc. */)
$scope.myOtherFunction = function() {
//
}
// etc.
}]
)
);
}();
장점 :
단점 :