Доступ к $scope в AngularJS factory?
Я новичок в AngularJS и считаю это очень интересным, но я немного не понимаю, о следующей ситуации.
app.factory('deleteFac', function($http){
var factory = {};
factory.edit = function(id){
$http.get('?controller=store&action=getDetail&id=' + id).
success(function(data, status){
/**
got an error on the following
when i use return data; and i get data undefined
in the controller which i get it because its doing a ajax call
you don't get data until the call first.
**/
$scope.detail = data;
})
}
return factory;
})
Я получаю сообщение об ошибке при назначении $scope
и использовании возвращаемых данных, так или иначе, я могу назначить возвращаемые данные $scope
?
Ответы
Ответ 1
Обычно вы не используете $scope
внутри factory, службы или поставщика. Обычно вы возвращаете promise
(возвращается $http
), а затем обрабатываете обещание в контроллере (где у вас есть $scope
).
factory.edit = function(id){
return $http.get('?controller=store&action=getDetail&id=' + id);
}
Функция контроллера:
$scope.edit = function(id) {
deleteFac.edit(id).then(function(response) {
$scope.something = response.model;
});
}
Ответ 2
Я думаю, вы имели в виду это:
app.factory('deleteFac', function($http){
var service = {};
factory.edit = function(id, success, error){
var promise = $http.get('?controller=store&action=getDetail&id=' + id);
if(success)
promise.success(success);
if(error)
promise.error(error);
};
return service;
});
Затем в вашем контроллере вы выполните:
function MyController($scope, deleteFac){
deleteFac.edit($scope.id, function(data){
//here you have access to your scope.
});
}
Ответ 3
Следующий трюк - очень плохая практика, но вы можете использовать его, если вы спешите:
Обмениваем $scope
на: angular.element('[ng-controller=CtrlName]').scope()
Ответ 4
Я думаю, что это самое чистое решение:
Сообщите мне, есть ли проблемы или улучшения.
(function(){
angular.controller('controllerName', controllerName);
controllerName.$inject = ['$scope', factory];
function controllerName($scope, factory){
var vm = this;
vm.data = factory.alertPopup();
}
angular.factory('factory', factory);
factory.$inject = ['externalServices'];
function factory(externalServices){
return {
returnData : returnData
}
function returnData(){
return externalServices.whatever();
}
}
})();
Ответ 5
Лично я хотел бы использовать область видимости из factory, поэтому вместо того, чтобы перемещать все, я передавал область как параметр от клиента, который вызывает factory.function().
Также у меня была такая же проблема при попытке использовать $scope.watch(...), так как мы не можем напрямую использовать $scope от фабрик или сервисов, но я хотел, чтобы это работало таким образом, поэтому я и хочу просто обновила мою функцию, чтобы иметь область действия как параметр и позволить клиенту factory отправить $scope. Итак, это было бы моим решением:
var app = angular.module("myApp", []);
app.factory('MyFactory', function($http) {
var factory = {};
//This is only for my own issue I faced.
factory.Images = {};
factory.myFunction = function(id, scope) {
//This is an example of how we would use scope inside a factory definition
scope.details = "Initial Value";
//In my case I was having this issue while using watch
scope.$watch('details' , function(newValue, oldValue) {
if(oldValue){
scope.log = "Details was updated to : " +newValue;
}
});
scope.details = "My Id is: "+id;
};
return factory;
});
//Controller: Factory Client.
app.controller("MyController", ['$scope', 'MyFactory', function($scope, MyFactory) {
MyFactory.myFunction(5, $scope);
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyController">
<span>{{details}} </span>
<hr>
<p>{{log}} </p>
</div>
Ответ 6
.factory('POPUP', function($ionicLoading, $ionicPopup) {
var self = this;
// THIS BLOCK SCREEN ! for loading ! Be carefoull !! ( deprecated: assign this to a var for security)
self.showLoading = function(title, message, scope){
scope.loading = true;
return $ionicLoading.show({ content: message, showBackdrop: false });
};
self.hideLoading = function(title, message, scope){
scope.loading = false;
return $ionicLoading.hide();
};
// NOT BLOCK SCREEN- SIMPLE ALERTS - Standards popups
self.showAlert = function(title, message, callback){
var alertPopup = $ionicPopup.alert({ title: title, template: message });
alertPopup.then(function(res) {
console.log('callback popup');
if (callback){ callback(); }
});
};
self.showConfirm = function(objectPopup, callback){
if (objectPopup === undefined){ objectPopup = { title: 'test confirm Popup', template: 'Message test Confirm POPUP' }; }
var alertPopup = $ionicPopup.confirm(objectPopup);
alertPopup.then(function(res) {
if (res) { callback(true); }
else { callback(false); }
});
};
return self;
})