【问题标题】:Javascript \ Angular function scope confusionJavascript \ Angular 函数范围混淆
【发布时间】:2016-07-31 03:44:10
【问题描述】:

抱歉,如果这很明显,我有点 Angular\Javascript 菜鸟。我有以下服务:

MyApp.service('ClientService', function ($http, $q, SharedData) {

    this.get = function () {
        var deferred = $q.defer();
        $http.get("/api/Client/")
            .success(function(data, status) {

                deferred.resolve(data);
            })
            .error(function(data, status) {
                deferred.reject(data);
            });

        return deferred.promise;
    };

    this.setCurrentClient = function (clientToSelect) {
        var deferred = $q.defer();
        var getCurrentClient = this.get();

        $http({ method: "POST", url: "/api/Client", data: clientToSelect })
            .success(function (data, status) {

                //Get the full selected client and all its properties rather than the list version
                getCurrentClient.then(
                     function (client) {
                         setCurrentClient(client);
                         setCurrentPeriod(client);
                     },
                     function (data) {
                         //uho something broke.
                     });

                deferred.resolve(data);
            })
            .error(function (data, status) {
                deferred.reject(data);
            });

        return deferred.promise;
    }

    .....
});

在 this.setCurrentClient 函数中,我通过 $http 调用后端,并在异步成功返回时通过变量 getCurrentClient 调用 get 函数。我最初尝试直接调用 get() 或 this.get() ,但都没有成功。 .success 回调函数中的上下文似乎是全局窗口上下文而不是服务上下文。上面的解决方案对我来说似乎有点混乱。有没有更好的方法来获取服务上下文并调用 get() 而不是使用方法 (var getCurrentClient = this.get()) 设置变量然后调用它 (getCurrentClient.then()) ? javascript\angular 范围和上下文有点迷失......

【问题讨论】:

  • 你看过 $resource 服务吗?看来这就是你真正追求的?
  • 这是纯 JavaScript 作用域。与 Angular 范围无关。您需要保存范围引用,并且应该从保存的引用中访问方法。 var self = this; self.setCurrentClient(); 否则你应该使用docs.angularjs.org/api/ng/function/angular.bind
  • 通过 $http 调用后端服务没有问题。我相信使用 $resource 的效果大致相同,但对于我们并没有真正使用的 RestFul 服务。异步回调是相同的。 @VigneswaranMarimuthu 我认为这基本上就是我最终得到的结果,即将外部范围 get() 方法保存在一个变量中以调用内部函数。我真的不明白为什么我必须这样做?为什么我不能只访问外部作用域?
  • 这就是 Angular service 的工作原理,通过实例化传递的构造函数。如果您使用了角度factory,则范围界定不会有问题。两者都创建service,但方式不同。
  • 正如我在回答中提到的,如果你想使用方法内部相同的服务,你可以跳过这个关键字到服务中,但是如果你想从控制器访问它们,那么你可以将你的函数传递给服务像 this.myFunction = myFunction; 这样的范围然后你可以在没有 this 关键字的情况下在服务内部使用 myFunction 或设置一个变量来调用你的函数。

标签: javascript angularjs


【解决方案1】:

我相信您不需要在服务中使用“this”,您只需将您的函数声明为function get() { ...,然后在 setCurrentClient 的回调中调用:

var getCurrentClient = get();

但是,如果您确实需要“this”,一个常见的模式是使用 var self = this; 或类似的东西 - 请参阅 this discussion

(顺便说一句,我还建议将您的函数和变量重命名为 var clientPromise = getCurrentClient(); 以提高可读性。)

【讨论】:

    【解决方案2】:

    我会说在这种情况下使用角度factory

    MyApp.factory('ClientService', function ClientFactory($http, $q, SharedData) {
    
        function get() {
            var deferred = $q.defer();
            $http.get("/api/Client/")
                .success(function(data, status) {
    
                    deferred.resolve(data);
                })
                .error(function(data, status) {
                    deferred.reject(data);
                });
    
            return deferred.promise;
        };
    
        function setCurrentClient(clientToSelect) {
            var deferred = $q.defer();
            var getCurrentClient = get();
    
            $http({ method: "POST", url: "/api/Client", data: clientToSelect })
                .success(function (data, status) {
    
                    //Get the full selected client and all its properties rather than the list version
                    getCurrentClient.then(
                         function (client) {
                             setCurrentClient(client);
                             setCurrentPeriod(client);
                         },
                         function (data) {
                             //uho something broke.
                         });
    
                    deferred.resolve(data);
                })
                .error(function (data, status) {
                    deferred.reject(data);
                });
    
            return deferred.promise;
        }
    
        .....
        // Expose the service methods
        return {
            get: get,
            setCurrentClient: setCurrentClient
            ...... (Expose what all methods you wanted to expose)
        };
    });
    

    【讨论】:

      【解决方案3】:

      这是我将如何使用你想要的服务..`当你尝试在 http 请求中调用 this.get 时,this 将在 Window 范围内寻找 get 方法,如果你打印这个控制台中的关键字,您可以看到没有 get 方法。 This 总是指您使用 this

      Object
          MyApp.service('ClientService', function ($http, $q, SharedData) {
      
                          var get = function () {
                              var deferred = $q.defer();
                              $http.get("/api/Client/")
                                  .success(function (data, status) {
      
                                      deferred.resolve(data);
                                  })
                                  .error(function (data, status) {
                                      deferred.reject(data);
                                  });
      
                              return deferred.promise;
                          };
      
                          var setCurrentClient = function (clientToSelect) {
                              var deferred = $q.defer();
      
                              $http({
                                      method: "POST",
                                      url: "/api/Client",
                                      data: clientToSelect
                                  })
                                  .success(function (data, status) {
      
                                      //Get the full selected client and all its properties rather than the list version
                                      get().then(
                                          function (client) {
                                              setCurrentClient(client);
                                              setCurrentPeriod(client);
                                          },
                                          function (data) {
                                              //uho something broke.
                                          });
      
                                      deferred.resolve(data);
                                  })
                                  .error(function (data, status) {
                                      deferred.reject(data);
                                  });
      
                              return deferred.promise;
                          }
                          this.get = get;
                          this.setCurrentClient = setCurrentClient;
                      });)
                  .error(function (data, status) {
                      deferred.reject(data);
                  });
      
              return deferred.promise;
          }
          this.get = get;
          this.setCurrentClient = setCurrentClient;
      })
      

      【讨论】:

        猜你喜欢
        • 2014-04-14
        • 1970-01-01
        • 2023-03-09
        • 1970-01-01
        • 1970-01-01
        • 2016-02-24
        • 2015-10-04
        • 2016-10-09
        • 2020-02-16
        相关资源
        最近更新 更多