t.then()不是一个函数;但是,正在返回延迟的object.promise

时间:2017-02-11 21:24:45

标签: angularjs

我意识到堆栈溢出中有一百万个这样的问题,我已经看了好几个。似乎总是有人没有回复承诺。这次情况并非如此......我绝对会在LoginFactory回复承诺。当我登录帖子时,我的控制器发生错误。我只能假设这是一些奇怪的捆绑和缩小错误与我的脚本;但是,我是棱角分明的新人。

为什么angular抱怨没有返回延迟对象?

var LoginFactory = function ($http, $q) {
console.log("calling login factory constructor");
return function (emailAddress, password, rememberMe) {
    var deferredObject = $q.defer();

    $http.post('/Account/Login', {
        Email: emailAddress,
        Password: password,
        RememberMe: rememberMe
    }).success(function (data) {
        console.log("in success", data);
        if (data === "True") {
            deferredObject.resolve({ success: true });
        } else {
            deferredObject.resolve({ success: true });
        }
    }).error(function () {
        console.log("in error");
        deferredObject.resolve({ success: false });
    });
    console.log("returning deferred object", deferredObject);
    return deferredObject.promise;
}
}

LoginFactory.$inject = ['$http', '$q'];  


var LoginController = function ($scope, $routeParams) {
$scope.loginForm = {
    emailAddress: '',
    password: '',
    rememberMe: false,
    returnUrl: $routeParams.returnUrl
};

$scope.login = function () {
    var result = LoginFactory($scope.loginForm.emailAddress, $scope.loginForm.password, $scope.loginForm.rememberMe);
    console.log("result in login func",result);
    result.then(function (result) {
        if (result.success) {
            if ($scope.loginForm.returnUrl !== undefined) {
                $location.path('/routeOne');
            } else {
                $location.path($scope.loginForm.returnUrl);
            }
        } else {
            $scope.loginForm.loginFailure = true;
        }
    });
}
}

LoginController.$inject = ['$scope', '$routeParams', '$location', 'LoginFactory'];  

enter image description here

添加缩小的脚本。回报承诺看起来很奇怪。我对js不太熟悉,不知道这是否正确

LoginFactory = function(n, t) {
return console.log("calling login factory constructor"),
    function(i, r, u) {
        var f = t.defer();
        return n.post("/Account/Login", {
            Email: i,
            Password: r,
            RememberMe: u
        }).success(function(n) {
            console.log("in success", n);
            n === "True" ? f.resolve({
                success: !0
            }) : f.resolve({
                success: !0
            })
        }).error(function() {
            console.log("in error");
            f.resolve({
                success: !1
            })
        }), console.log("returning deferred object", f), f.promise
    }
};
LoginFactory.$inject = ["$http", "$q"];

2 个答案:

答案 0 :(得分:0)

您必须返回deferredObject(不是deferredObject.promise) 结果是Rails.root.join("")

当加载promise时,then函数将被执行

答案 1 :(得分:0)

这是所谓的John Papa风格和$inject注释的底层。

LoginFactory变量导致在多个范围中具有相同的名称(如'function scope',而不是'Angular scope');匿名函数和数组注释永远不会发生的事情。

函数注释和函数签名不匹配:

var LoginController = function ($scope, $routeParams) { ... }

LoginController.$inject = ['$scope', '$routeParams', '$location', 'LoginFactory'];  

这导致从父作用域获取LoginFactory,它是工厂函数,而不是实例。因此LoginFactory(...)调用的结果是函数,而不是承诺(这是console.log输出的内容。)

应该是

var LoginController = function ($scope, $routeParams, $location, LoginFactory) { ... }

可以做两件事,永远不要再发生这种情况。

一个是使用命名函数而不是变量,因此可以提升$inject注释。这允许并排注释和功能签名:

LoginController.$inject = ['$scope', '$routeParams', '$location', 'LoginFactory'];  

function LoginController ($scope, $routeParams, $location, LoginFactory) { ... }

另一个是TDD。在编写应用程序时同时编写单元测试。这样就可以通过消除潜在的原因来发现新手的错误并推断出复杂的错误。如果LoginFactory在编写LoginController时已经过测试,那么DI就会出错了。

此外,上面的代码使用了弃用的success方法和deferred antipattern