Accessing $scope in AngularJS factory?

前端 未结 7 1203
我寻月下人不归
我寻月下人不归 2020-11-27 13:11

I am new to AngularJS and find it very interesting, but I am a bit unclear about the following situation.

app.factory(\'deleteFac\', function($http){

var fa         


        
相关标签:
7条回答
  • 2020-11-27 13:24

    The following trick is a very bad practice, but you can use it if you are in a hurry:

    Exchange the $scope with: angular.element('[ng-controller=CtrlName]').scope()

    0 讨论(0)
  • 2020-11-27 13:24

    I know this question is old, but this is what worked for me

    app.factory('myFactory',function(){
    
        let toRet = {
            foo: foo
        }
    
        return toRet;
    
        function foo(){ // This function needs to use passed scope.
            let $scope = toRet.$scope;
            // Do stuff with $scope.
        }
    });
    
    app.controller('myController',function($scope,myFactory){
    
        myFactory.$scope = $scope;
        /*
            We could just pass $scope as a parameter to foo, but this is
            for cases where for whatever reason, you cannot do this.
        */
        myFactory.foo();
    
    });
    
    0 讨论(0)
  • 2020-11-27 13:28

    I guess you meant this:

    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;
    });
    

    Then in your controller you do:

    function MyController($scope, deleteFac){
       deleteFac.edit($scope.id, function(data){
           //here you have access to your scope.
       });
    }
    
    0 讨论(0)
  • 2020-11-27 13:32

    You don't typically use $scope inside a factory, service or provider. Usually, you would return the promise (returned by $http) and then handle the promise in a controller (where you do have $scope).

    factory.edit = function(id){
        return $http.get('?controller=store&action=getDetail&id=' + id);
    }
    

    Controller function:

    $scope.edit = function(id) {
    
        deleteFac.edit(id).then(function(response) {
            $scope.something = response.model;
        });
    }
    
    0 讨论(0)
  • 2020-11-27 13:41

    Personally I would like to use scope from the factory, so, instead of moving all out I would pass the scope as parameter from the client which is calling to the factory.function().

    Also I was having this same issue when trying to use $scope.watch(...) since we cannot use directly $scope from factories or services but I wanted to have this working in this way, so that is why I just updated my function to have scope as parameter and let the factory's client to send the $scope. So, this would be my solution:

    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's 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>

    I hope this can help. Regards.

    0 讨论(0)
  • 2020-11-27 13:43

    I think this is the cleanest solution:

    Let me know if there is problem or improvement.

    (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();
        }
      }
    })();
    
    0 讨论(0)
提交回复
热议问题