简体   繁体   English

Javascript \\ Angular函数作用域混淆

[英]Javascript \ Angular function scope confusion

Apologies if this is obvious I am a bit of an Angular\\Javascript noob. 抱歉,这很明显,我有点Angular \\ Javascript noob。 I have the following service: 我有以下服务:

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

    .....
});

In the this.setCurrentClient function I make a call to the backend via $http and on its asynchronous successful return I call the get function via a variable getCurrentClient. 在this.setCurrentClient函数中,我通过$ http调用后端,并在其异步成功返回时通过变量getCurrentClient调用get函数。 I originally tried to call get() or this.get() directly and neither worked. 我最初尝试直接调用get()或this.get(),但都没有用。 The context in the .success callback function seems to be the global window context not the service context. .success回调函数中的上下文似乎是全局窗口上下文,而不是服务上下文。 The above solution seems a little messy to me. 上述解决方案对我来说似乎有点混乱。 Is there a better way to get the service context and call get() rather than setting a variable with the method (var getCurrentClient = this.get()) and then calling it (getCurrentClient.then()) ? 是否有更好的方法来获取服务上下文并调用get(),而不是使用方法(var getCurrentClient = this.get())设置变量然后再调用(getCurrentClient.then())? A little lost with javascript\\angular scope and contexts... javascript \\ angular范围和上下文有点迷失...

I believe you don't need to use "this" in your service, you can just declare your function as function get() { ... and then, in the callback in setCurrentClient, call: 我相信您不需要在服务中使用“ this”,只需将函数声明为function get() { ... ,然后在setCurrentClient的回调中调用:

var getCurrentClient = get();

However, if you do really need the "this", a common pattern is using var self = this; 但是,如果确实需要“ this”,则常见的模式是使用var self = this; or something like that - see this discussion . 或类似的东西-请参阅此讨论

(as an aside, I would also recommend renaming your function and variables to have var clientPromise = getCurrentClient(); for better readability.) var clientPromise = getCurrentClient(); ,我还建议重命名您的函数和变量,使其具有var clientPromise = getCurrentClient();以获得更好的可读性。)

I would say use angular factory in this case. 我会说在这种情况下使用角度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)
    };
});

Here is how i would use service as you want..`When you will try to call this.get inside http request then this will look for get method in Window scope and if you print this keyword in console you can see there is no get method. 下面是我会用服务为您want..`When你会尝试打电话给this.get内的HTTP请求,那么将寻找get方法在窗口范围,如果你在控制台中,您可以看到打印这个关键字有没有get方法。 This always refer to the Object where you are using this 总是指您正在使用 对象的对象

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM