Saya memiliki tiga pengontrol yang sangat mirip. Saya ingin memiliki pengontrol yang diperluas ketiga dan fungsinya.
Saya memiliki tiga pengontrol yang sangat mirip. Saya ingin memiliki pengontrol yang diperluas ketiga dan fungsinya.
Jawaban:
Mungkin Anda tidak memperpanjang pengontrol tetapi dimungkinkan untuk memperluas pengontrol atau membuat pengontrol tunggal sebagai campuran dari beberapa pengontrol.
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.
}]);
Ketika pengendali induk dibuat, logika yang terkandung di dalamnya juga dieksekusi. Lihat $ controller () untuk informasi lebih lanjut tentang tetapi hanya $scope
nilai yang harus dilewati. Semua nilai lain akan disuntikkan secara normal.
@ mwarren , kekhawatiran Anda diatasi secara otomatis dengan injeksi ketergantungan sudut. Yang Anda butuhkan adalah menyuntikkan $ scope, meskipun Anda bisa mengganti nilai yang disuntikkan lainnya jika diinginkan. Ambil contoh berikut:
(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>
Meskipun $ document tidak dimasukkan ke dalam 'simpleController' ketika itu dibuat oleh 'complexController' $ document disuntikkan untuk kita.
$.extend()
, Anda cukup menelepon$controller('CtrlImpl', {$scope: $scope});
angular.extend
(atau $.extend
) sebenarnya berarti memperluas $scope
satu - satunya, tetapi jika pengendali basis Anda juga mendefinisikan beberapa properti (misalnya this.myVar=5
), Anda hanya memiliki akses ke this.myVar
dalam pengontrol perpanjangan ketika menggunakanangular.extend
handleSubmitClick
yang akan memanggil handleLogin
yang pada gilirannya memiliki loginSuccess
dan loginFail
. Jadi, dalam controller diperpanjang saya kemudian harus membebani handleSubmitClick
, handleLogin
dan loginSucess
untuk yang benar loginSuccess
fungsi yang akan digunakan.
Untuk warisan Anda dapat menggunakan pola warisan JavaScript standar. Berikut ini adalah demo yang digunakan$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);
Jika Anda menggunakan controllerAs
sintaks (yang sangat saya rekomendasikan), akan lebih mudah untuk menggunakan pola pewarisan klasik:
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);
Cara lain bisa dengan membuat fungsi konstruktor "abstrak" yang akan menjadi basis controller Anda:
function BaseController() {
this.click = function () {
//some actions here
};
}
module.controller('ChildCtrl', ['$scope', function ($scope) {
BaseController.call($scope);
$scope.anotherClick = function () {
//other actions
};
}]);
Yah, saya tidak begitu yakin apa yang ingin Anda capai, tetapi biasanya Layanan adalah cara untuk pergi. Anda juga dapat menggunakan karakteristik pewarisan Lingkup Angular untuk berbagi kode antara pengontrol:
<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( )
menjadi cara yang jauh lebih bersih untuk melakukannya, karena di situlah sebenarnya didefinisikan?
Anda tidak memperpanjang pengontrol. Jika mereka melakukan fungsi dasar yang sama maka fungsi-fungsi tersebut perlu dipindahkan ke layanan. Layanan itu dapat disuntikkan ke pengendali Anda.
Solusi lain yang baik diambil dari artikel ini :
// 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;
});
}]);
Anda dapat membuat layanan dan mewarisi perilakunya di pengontrol apa pun hanya dengan menyuntikkannya.
app.service("reusableCode", function() {
var reusableCode = {};
reusableCode.commonMethod = function() {
alert('Hello, World!');
};
return reusableCode;
});
Kemudian di controller Anda yang ingin Anda rentangkan dari layanan reusableCode di atas:
app.controller('MainCtrl', function($scope, reusableCode) {
angular.extend($scope, reusableCode);
// now you can access all the properties of reusableCode in this $scope
$scope.commonMethod()
});
DEMO PLUNKER: http://plnkr.co/edit/EQtj6I0X08xprE8D0n5b?p=preview
Anda dapat mencoba sesuatu seperti ini (belum diuji):
function baseController(callback){
return function($scope){
$scope.baseMethod = function(){
console.log('base method');
}
callback.apply(this, arguments);
}
}
app.controller('childController', baseController(function(){
}));
Anda dapat memperluas dengan layanan , pabrik , atau penyedia . mereka sama tetapi dengan tingkat fleksibilitas yang berbeda.
di sini contoh menggunakan pabrik: 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
});
Dan di sini Anda dapat menggunakan fungsi toko juga:
<div ng-controller="myController">
<input ng-blur="myFactory.store()" />
</div>
Anda dapat langsung menggunakan contoh $ 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});
}]);
Anda dapat menggunakan sintaks Angular "sebagai" yang dikombinasikan dengan pewarisan JavaScript biasa
Lihat lebih detail di sini http://blogs.microsoft.co.il/oric/2015/01/01/base-controller-angularjs/
Saya menulis fungsi untuk melakukan ini:
function extendController(baseController, extension) {
return [
'$scope', '$injector',
function($scope, $injector) {
$injector.invoke(baseController, this, { $scope: $scope });
$injector.invoke(extension, this, { $scope: $scope });
}
]
}
Anda bisa menggunakannya seperti ini:
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.
}]
)
);
}();
Pro:
Cons:
Saya menganggap memperluas pengontrol sebagai praktik buruk. Alih-alih menempatkan logika Anda bersama ke dalam layanan. Objek yang diperluas dalam javascript cenderung menjadi agak rumit. Jika Anda ingin menggunakan warisan, saya akan merekomendasikan naskah. Namun, pengontrol tipis adalah cara yang lebih baik untuk masuk ke sudut pandang saya.