在 AngularJS 工厂中访问 $scope?

IT技术 javascript angularjs
2021-03-13 06:21:16

我是 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

6个回答

您通常不会$scope在工厂、服务或提供商内部使用通常,您会返回promise(由 返回$http),然后在控制器(您有$scope)中处理Promise

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;
    });
}
为什么不将$scope作为参数传递给函数edit(),如下所示, factory.edit = function(id, $scope){ return $http.get('?controller=store&action=getDetail&id=' + id); }然后你可以$scope在工厂函数中做任何你想做的事情
2021-04-30 06:21:16
@bluebill1049 这就是我在评论中的意思。在这种情况下这是正确的答案 - 我会使用.doneor.then代替.success但除此之外它是好的 imo 。
2021-05-05 06:21:16
将是很好的更新这个答案用then,而不是success作为success现在已经过时:docs.angularjs.org/api/ng/service/$http#deprecation-notice
2021-05-07 06:21:16

我猜你的意思是:

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.
   });
}
是的,谢谢埃德温,我是说这个,谢谢你的例子
2021-04-15 06:21:16
@BenjaminGruenbaum 介意提供任何参考吗?
2021-04-17 06:21:16
@EdwinDalorzo 如果有人要写一本关于 JS Promise的(好)书,变化是它会是大约 100 个非常具体的人之一。我上面列出的三个可能是该列表的前 10 名。Kris 在 JS 中普及了 promises,编写了令人惊叹的 Q 库,使这一切成为可能,Domenic 在 A+ 规范上做了大量工作并将 promises 引入 ES6 和 DOM 和 Petka,他编写了第一个快速 promise 实现它们在 NodeJS 的狭小空间中确实可行。问题是这个领域在 JS 中发展得非常快,书籍也不会很好用 :)
2021-04-29 06:21:16
-1 这是一个Promise反模式。返回Promise更不容易出错,通常更可取。
2021-05-06 06:21:16
当然,在我离开这个之前在这里,但删除它作为,因为它真的很简单。这是使用Promise作为美化的回调,更不用说if那里的冗余检查了。我认为大卫的解决方案运作良好。
2021-05-06 06:21:16

以下技巧是一种非常糟糕的做法,但如果您赶时间,可以使用它:

交换$scopeangular.element('[ng-controller=CtrlName]').scope()

这看起来很脏,但可能是一个小技巧:) 无论如何感谢您的回答(加上你说这是一个坏习惯)
2021-04-21 06:21:16
这是 2017 年。如果这个答案对你有帮助,而且你刚刚开始你的项目,你可能想考虑 vue.js。
2021-05-01 06:21:16

就我个人而言,我想使用工厂中的范围,因此,我不会将范围作为参数从调用 factory.function() 的客户端传递,而不是全部移出。

我在尝试使用 $scope.watch(...) 时也遇到了同样的问题,因为我们不能直接从工厂或服务中使用 $scope,但我想让它以这种方式工作,所以这就是为什么我刚刚更新了我的函数将范围作为参数,并让工厂的客户端发送 $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'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>

我希望这会有所帮助。问候。

我认为这是最干净的解决方案:

让我知道是否有问题或改进。

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