मेरे पास तीन नियंत्रक हैं जो काफी समान हैं। मैं एक नियंत्रक चाहता हूं जो ये तीनों अपने कार्यों को बढ़ाते हैं और साझा करते हैं।
मेरे पास तीन नियंत्रक हैं जो काफी समान हैं। मैं एक नियंत्रक चाहता हूं जो ये तीनों अपने कार्यों को बढ़ाते हैं और साझा करते हैं।
जवाबों:
शायद आप किसी नियंत्रक का विस्तार नहीं करते हैं, लेकिन नियंत्रक का विस्तार करना या एकल नियंत्रक को कई नियंत्रकों का मिश्रण बनाना संभव है।
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
मूल्य को पारित करने की आवश्यकता है। अन्य सभी मूल्यों को सामान्य रूप से इंजेक्ट किया जाएगा।
@mwarren , Angular निर्भरता इंजेक्शन द्वारा आपकी चिंता को ऑटो-जादुई रूप से ध्यान रखा जाता है। आप सभी की जरूरत है $ गुंजाइश इंजेक्षन करने के लिए है, हालांकि आप अन्य इंजेक्शन मूल्यों को ओवरराइड कर सकते हैं यदि वांछित। निम्नलिखित उदाहरण लें:
(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>
हालांकि 'डॉक्यूमेंटकंट्रोलर' द्वारा बनाए जाने पर $ डॉक्यूमेंट 'simpleController' में पारित नहीं होता है, लेकिन $ डॉक्यूमेंट हमारे लिए इंजेक्ट किया जाता है।
$.extend()
, आप बस कॉल कर सकते हैं$controller('CtrlImpl', {$scope: $scope});
angular.extend
(या $.extend
) वास्तव में $scope
केवल विस्तार करने का मतलब है , लेकिन यदि आपका आधार नियंत्रक कुछ गुणों (जैसे this.myVar=5
) को भी परिभाषित करता है , तो आपके पास केवल उपयोग this.myVar
में आने वाले नियंत्रक तक पहुंच हैangular.extend
handleSubmitClick
जो कहेंगे handleLogin
जो बारी में था एक loginSuccess
और loginFail
। तो, मेरी विस्तारित नियंत्रक में मैं तो ओवरलोड था handleSubmitClick
, handleLogin
है, और loginSucess
सही के लिए loginSuccess
समारोह में इस्तेमाल किया जा करने के लिए।
उत्तराधिकार के लिए आप मानक जावास्क्रिप्ट वंशानुक्रम पैटर्न का उपयोग कर सकते हैं। यहाँ एक डेमो है जो उपयोग करता है$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
};
}]);
ठीक है, मैं बिल्कुल निश्चित नहीं हूं कि आप क्या हासिल करना चाहते हैं, लेकिन आमतौर पर सेवाएं जाने का रास्ता हैं। आप नियंत्रकों के बीच कोड साझा करने के लिए कोणीय की स्कोप इनहेरिटेंस विशेषताओं का भी उपयोग कर सकते हैं:
<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>
आप सीधे $ नियंत्रक ('पेरेंटकंट्रोलर', {$ गुंजाइश: $ गुंजाइश}) उदाहरण का उपयोग कर सकते हैं
module.controller('Parent', ['$scope', function ($scope) {
//code
}])
module.controller('CtrlImplAdvanced', ['$scope', '$controller', function ($scope, $controller) {
//extend parent controller
$controller('CtrlImpl', {$scope: $scope});
}]);
आप सादे जावास्क्रिप्ट विरासत के साथ संयुक्त "सिंटैक्स" के रूप में कोणीय "का उपयोग कर सकते हैं
अधिक विवरण यहां देखें 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.
}]
)
);
}();
पेशेवरों:
विपक्ष:
मैं मौजूदा नियंत्रकों को बुरा व्यवहार मानता हूं। बल्कि अपने साझा तर्क को एक सेवा में लगाएं। जावास्क्रिप्ट में विस्तारित वस्तुएं बल्कि जटिल होती हैं। यदि आप विरासत का उपयोग करना चाहते हैं, तो मैं टाइपस्क्रिप्ट की सिफारिश करूंगा। फिर भी, मेरे दृष्टिकोण में जाने के लिए पतले नियंत्रक बेहतर हैं।