将 $q 与 $http 一起使用
Using $q with $http
在我的 $routeProvider 中,我有一个解决方案 属性 在实例化我的控制器之前从 API 获取数据。为什么当我将 $q 与 $http 服务一起使用时,我可以将数据传递到我的控制器。他们不是在做同样的事情吗?
这是我无法将数据传递给控制器的原始方法:
AccountService.js
app.factory('AccountService', ['$http', '$q', function ($http, $q) {
return {
GetAccounts: function () {
return $http.get('api/Account/GetAccounts')
.then(function success(response) {
return response;
}, function error(response) {
̶r̶e̶t̶u̶r̶n̶ throw console.log("Oops!");
});
},
};
}]);
为了将数据传递到控制器,我将 GetAccounts 更改为:
app.factory('AccountService', ['$http', '$q', function ($http, $q) {
return {
GetAccounts: function () {
var deferred = $q.defer();
$http.get('api/Account/GetAccounts')
.then(function (data) {
deferred.resolve(data.data);
})
.catch(function (response) {
deferred.reject(response);
})
return deferred.promise;
},
};
}]);
route.js
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/users', {
template: '<admin accounts="$resolve.accounts"></admin>',
resolve: {
accounts: function (AccountService) {
return AccountService.GetAccounts()
.then(function (data) {
return data;
})
}
}
})
}]);
$q 是 Angulars 的承诺包装器。 $http returns 一个直接的 promise 所以无论你是用一个新的 $q 还是直接用 $http 创建一个新的 promise,它们都是一样的
所以基本上您不必做您在 AccountService 中所做的事情,只需要这样做:
app.factory('AccountService', ['$http', function ($http) {
return {
GetAccounts: function () {
return $http.get('api/Account/GetAccounts')
.then(function (data) {
return data.data;
})
},
};
}]);
我会保存 .catch() 以供您处理并可能将错误包装在一个很好的错误结构中,除非您的后端已经这样做了。
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/users', {
template: '<admin accounts="$resolve.accounts"></admin>',
resolve: {
accounts: function (AccountService) {
return AccountService.GetAccounts()
.catch( function(err) { ̶r̶e̶t̶u̶r̶n̶ throw new BusinessError( err ) } )
}
}
})
}]);
或者让调用 controller/component 处理它,这是一个架构决定。
在我的 $routeProvider 中,我有一个解决方案 属性 在实例化我的控制器之前从 API 获取数据。为什么当我将 $q 与 $http 服务一起使用时,我可以将数据传递到我的控制器。他们不是在做同样的事情吗?
这是我无法将数据传递给控制器的原始方法:
AccountService.js
app.factory('AccountService', ['$http', '$q', function ($http, $q) {
return {
GetAccounts: function () {
return $http.get('api/Account/GetAccounts')
.then(function success(response) {
return response;
}, function error(response) {
̶r̶e̶t̶u̶r̶n̶ throw console.log("Oops!");
});
},
};
}]);
为了将数据传递到控制器,我将 GetAccounts 更改为:
app.factory('AccountService', ['$http', '$q', function ($http, $q) {
return {
GetAccounts: function () {
var deferred = $q.defer();
$http.get('api/Account/GetAccounts')
.then(function (data) {
deferred.resolve(data.data);
})
.catch(function (response) {
deferred.reject(response);
})
return deferred.promise;
},
};
}]);
route.js
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/users', {
template: '<admin accounts="$resolve.accounts"></admin>',
resolve: {
accounts: function (AccountService) {
return AccountService.GetAccounts()
.then(function (data) {
return data;
})
}
}
})
}]);
$q 是 Angulars 的承诺包装器。 $http returns 一个直接的 promise 所以无论你是用一个新的 $q 还是直接用 $http 创建一个新的 promise,它们都是一样的
所以基本上您不必做您在 AccountService 中所做的事情,只需要这样做:
app.factory('AccountService', ['$http', function ($http) {
return {
GetAccounts: function () {
return $http.get('api/Account/GetAccounts')
.then(function (data) {
return data.data;
})
},
};
}]);
我会保存 .catch() 以供您处理并可能将错误包装在一个很好的错误结构中,除非您的后端已经这样做了。
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/users', {
template: '<admin accounts="$resolve.accounts"></admin>',
resolve: {
accounts: function (AccountService) {
return AccountService.GetAccounts()
.catch( function(err) { ̶r̶e̶t̶u̶r̶n̶ throw new BusinessError( err ) } )
}
}
})
}]);
或者让调用 controller/component 处理它,这是一个架构决定。