Как сделать прототип из 2 одинаковых контроллеров в angularjs?
В моем приложении 2 практически одинаковых контроллера. Многие функции одинаковы, поэтому я бы хотел их прототипировать. Это контроллер № 1:
c2gcontroller.js
angular.module('c2gyoApp')
.controller('C2gCtrl', function($scope) {
// some unique stuff
$scope.feeDay = 59;
...
// the identical functions
$scope.getMinutes = function(minutes) {
var duration = moment.duration(minutes, 'm');
return duration.minutes();
};
...
});
и контроллер № 2:
c2gbcontroller.js
angular.module('c2gyoApp')
.controller('C2gbCtrl', function($scope) {
// some unique stuff
$scope.feeDay = 89;
...
// the identical functions
$scope.getMinutes = function(minutes) {
var duration = moment.duration(minutes, 'm');
return duration.minutes();
};
...
});
Я пытался положить $scope.getMinutes
в завод:
smfactory.js
angular.module('c2gyoApp')
.factory('smfactory', function() {
return {
getHours: function(minutes) {
var duration = moment.duration(minutes, 'm');
return Math.ceil(duration.asHours() % 24);
}
};
});
Я ввел smfactory
в c2gcontroller.js
c2gcontroller.js (попытка №1)
angular.module('c2gyoApp')
.controller('C2gCtrl', function($scope, smfactory) {
...
// the identical functions
$scope.getHours = smfactory.getHours(minutes);
...
});
Это приводит к ошибке, что минуты не определены
line 33 col 42 'minutes' is not defined.
Итак, я попробовал:
c2gcontroller.js (попытка № 2)
angular.module('c2gyoApp')
.controller('C2gCtrl', function($scope, smfactory) {
...
// the identical functions
$scope.getMinutes = function(minutes) {
return smfactory.getHours(minutes);
};
...
});
что не приводит к ошибке, но мое приложение перестало отвечать на запросы. В принципе $scope.getMinutes
ничего не возвращает сейчас.
Я много читал и смотрел об услугах, фабриках, провайдерах AngularJS, но я не знаю, куда идти дальше. Какой будет правильный способ создания прототипа? c2gcontroller.js
а также c2gbcontroller.js
?
2 ответа
Как насчет псевдо-наследования с angular.extend
/* define a "base" controller with shared functionality */
.controller('baseCtrl', ['$scope', ..
function($scope, ...) {
$scope.getMinutes = function(minutes) {
var duration = moment.duration(minutes, 'm');
return duration.minutes();
};
.controller('C2gCtrl', ['$controller', '$scope', ...
function($controller, $scope, ...) {
// copies the functionality from baseCtrl to this controller
angular.extend(this, $controller('baseCtrl', {$scope: $scope}));
// some unique stuff
$scope.feeDay = 59;
})
.controller('C2gbCtrl', ['$controller', '$scope', ...
function($controller, $scope, ...) {
// copies the functionality from baseCtrl to this controller
angular.extend(this, $controller('baseCtrl', {$scope: $scope}))
// some unique stuff
$scope.feeDay = 89;
})
Вот где используется сочетание потрясающей JavaScript, и controller as
Синтаксис действительно пригодится.
Если мы вытащим ваши общие функции из простого старого объекта:
var commonStuff = {
getHours: function(minutes) {
var duration = moment.duration(minutes, 'm');
return Math.ceil(duration.asHours() % 24);
}
};
Затем, если мы реорганизуем наш контроллер в обычный JS-объект, мы можем дополнить его микшированием одним из двух способов. Либо непосредственно на сам объект, либо через прототип.
//Using the instance
function MyCtrl(){
var vm = this;
angular.extend(vm, commonStuff);
//Other stuff
}
//Or via the prototype
function MyCtrl(){
var vm = this;
}
//Controller specific
MyCtrl.prototype = {
};
angular.extend(MyCtrl.prototype, commonStuff);
Самым большим отличием является то, что теперь вы можете просто ссылаться на контроллер напрямую с помощью controller as
синтаксис.
<div ng-controller="myCtrl as ctrl">
<a href="" ng-click="ctrl.getHours(120)">Get Hours</a>
</div>