在AngularJS工厂中访问$ scope?

Bru*_*uce 62 javascript angularjs

我是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;
})
Run Code Online (Sandbox Code Playgroud)

当我分配$scope并使用返回数据时,我收到错误,无论如何我可以将返回数据分配给$scope

Dav*_*yon 79

您通常不在$scope工厂,服务或提供商内部使用.通常,您将返回promise(返回者$http)然后在控制器中处理promise(您确实拥有$scope).

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

控制器功能:

$scope.edit = function(id) {

    deleteFac.edit(id).then(function(response) {
        $scope.something = response.model;
    });
}
Run Code Online (Sandbox Code Playgroud)

  • @ bluebill1049这就是我在评论中的意思.在这种情况下,这是正确的答案 - 我使用`.done`或`.then`而不是`.success`但除此之外它是好的imo. (3认同)

Edw*_*rzo 13

我想你的意思是:

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;
});
Run Code Online (Sandbox Code Playgroud)

然后在你的控制器中你做:

function MyController($scope, deleteFac){
   deleteFac.edit($scope.id, function(data){
       //here you have access to your scope.
   });
}
Run Code Online (Sandbox Code Playgroud)

  • -1这是一种承诺反模式.返回承诺不易出错,通常更可取. (2认同)
  • @EdwinDalorzo如果有人要在JS上写一本关于承诺的好书,那么变化就会是~100个非常具体的人之一.我列出的三个可能在该列表的前10名.Kris在JS中推广了承诺,创作了令人惊叹的Q库,使得这一切成为可能,Domenic在A +规范上做了大量工作并获得了ES6以及DOM和Petka的承诺,他们编写了第一个快速承诺实现他们在NodeJS的狭窄地方真的很可行.问题是这个领域在JS中发展得非常快,书籍也不会很好用:) (2认同)

Fan*_*nto 9

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

兑换$scope:angular.element('[ng-controller=CtrlName]').scope()

  • 这是 2017 年。如果这个答案对你有帮助,并且你刚刚开始你的项目,你可能需要考虑 vue.js。 (2认同)

Osw*_*ldo 5

就我个人而言,我想使用工厂中的范围,因此,我不会将范围作为参数从调用 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);
}]);
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

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