Это правильный способ привязки фабрики к контроллеру?
У меня есть следующий код в моем модуле:
.controller('ModalInstanceCtrl', function($rootScope, $scope, emailService) {
$scope.emailService = emailService; // Good or not; if not, why?
$scope.showed = false;
$rootScope.$watch('showed', function () { $scope.showed = $rootScope.showed; }); // In case you wonder why I did this - I'm using this trick to prevent watch from firing twice, because that would happen if I remove the watch below and put its code here.
$scope.$watch('showed', function () {
if (!$rootScope.showed) return;
$scope.selected = 0;
$scope.primary = true;
$scope.verified = true;
if (emailService.emails.length == 0) emailService.load();
});
$scope.EmailSelected = function () {
emailService.setCurrent($scope.selected);
$scope.primary = emailService.emails[$scope.selected].primary;
$scope.verified = emailService.emails[$scope.selected].verified;
};
});
.factory('emailService', function($resource, $http) {
var emails = []; // [{email: 'sample@email.dom', verified: true, primary: false}, ...]
var selected = 0;
function sendreq(action, email){
$http({
method: 'POST',
url: '/email/',
data: "action_" + action + "=&email=" + email,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function(response) {
console.log(response.data);
return true;
}, function(data){
return data;
});
}
return {
emails: emails,
selected: selected,
setCurrent: function(curr){
selected = curr;
},
load: function(){
$resource('/api/email/?format=json').query({},
function success(result) {
emails.push.apply(emails, result);
});
},
add: function(email) {
for (var e in emails) if (emails[e].email == email) return false;
return sendreq('add', email);
},
remove: function() {
sendreq('remove', emails[selected].email);
}
}
})
И этот код в моем шаблоне HTML:
<div ng-repeat="e in emailService.emails">
<input type="radio" ng-model="$parent.selected" ng-value="$index" ng-change="EmailSelected()" id="email_{{ $index }}" name="email">
<label for="email_{{ $index }}" ng-bind='e.email'></label> <span ng-show="e.verified">Verified</span> <span ng-show="e.primary">Primary</span>
</div>
<div><button ng-disabled="primary" ng-click="emailService.remove()">Remove</button></div>
<form novalidate>
<input class="form-control" type="email" name="email" ng-model="email" placeholder="Email">
<input type="submit" ng-disabled="email === undefined" ng-click="emailService.add(email)" value="Add Email Address">
</form>
И я хочу спросить, правильно ли я собрал модуль и шаблон, потому что я работаю с AngularJS впервые. В частности, я хочу спросить, правильно ли привязывать всю фабрику к сфере? Также, если у кого-то есть больше времени, он может посмотреть на другой код, чтобы увидеть, все ли правильно или нет. Не стесняйтесь писать любые предложения о моем коде.
Заранее спасибо!
2 ответа
Это всегда зависит от конкретного случая.
Таким образом, стандартные методы обертки
$scope.add = (...args) => emailService.add(...args);
могут быть опущены, а также их тесты в спецификации контроллера.
Другое преимущество заключается в том, что он предоставляет существующий объект для правильной привязки данных и наследования области свойств скалярной области действия:
<parent-scope>
<p ng-init="emailService.selected = 0"></p>
<child-scope>
<p ng-init="emailService.selected = 1"></p>
{{ emailService.selected === $parent.emailService.selected }}
</child-scope>
</parent-scope>
Это, конечно, не будет работать, как ожидалось, если нет emailService
объект. Это особенно полезно, когда синтаксис controllerAs не используется.
Нет ничего плохого в том, чтобы предоставить сервису область действия - если его API соответствует области контроллера. И это может указывать на наличие антипаттерна, если он этого не делает, или если слишком много сервисов используются таким образом.
Почему вы хотите связать весь сервис? Я не вижу необходимости в вашем коде. Вы вызываете части службы, используя обработчик службы, нет особой необходимости помещать всю службу в область действия.