Return 从 AngularJS API 服务到控制器的值
Return a value from AngularJS API service to controller
如果我有这样的服务:
app.factory('User', function($http, User) {
var User = function(data) {
angular.extend(this, data);
};
User.prototype.create = function() {
var user = this;
return $http.post(api, user.getProperties()).success(function(response) {
user.uid = response.data.uid;
}).error(function(response) {
});
};
User.get = function(id) {
return $http.get(url).success(function(response) {
return new User(response.data);
});
};
return User;
});
如何在控制器中获取在 get()
函数中创建的 User
?
目前我拥有的是:
app.controller('UserCtrl', function($scope, User) {
$scope.user = null;
User.get($routeParams.rid).success(function(u) {
$scope.user = new User(u.data);
});
});
问题是 UserCtrl
得到的是 api 响应,而不是工厂中 success()
返回的值。我更愿意在工厂中创建新用户,而不是将 api 响应传递给控制器。
我觉得你的 returns 有点乱。我个人会这样写
app.factory('User', function ($http) {
var user = {
new: function (data) {
return $http.post(api, data);
},
get: function (id) {
$http.get(url).success(function (response) {
return user.new(response.data);
});
}
};
return user;
});
然后从你的控制器里面..
app.controller('UserCtrl', function($scope, User) {
$scope.user = null;
User.get($routeParams.rid).success(function(u) {
$scope.user = u.data;
});
});
编辑:2015 年 5 月 5 日
我了解了 deferred anti-pattern while trying to answer this 。
所以我们可以避免使用$q.defer()
,使用下面的代码可以达到同样的效果。
服务
User.get = function(id) {
return $http.get(url).then(function(response) {
return new User(response.data);
});
};
控制器
User.get($routeParams.rid).then(function(u) {
$scope.user = u;
});
原回答如下:
我认为您正在寻找的是 $q
服务,它允许您对来自异步 $http
服务的响应进行一些 post 处理,然后 return 它作为对控制器的承诺。在此处查看文档 https://docs.angularjs.org/api/ng/service/$q
因此,在您的工厂中注入 $q
服务并更改您的 User.get
功能,如下所示。
User.get = function(id) {
var deferred = $q.defer();
$http.get(url).success(function(response) {
deferred.resolve(new User(response.data));
}).error(function(error) {
deferred.reject(error);
});
return deferred.promise;
};
然后在你的控制器中你可以做
User.get($routeParams.rid).then(function(u) {
$scope.user = u;
}, function(error) {
//log error
});
有类似的问题,当我将 'response.data' 传递给 def.resolve 时,它从控制器中抛出未定义。于是直接通过response就成功了
var def = $q.defer();
$http.get('http://localhost:3000/api/services')
.success(function (response) {
***def.resolve(response);***
})
.error(function (error) {
def.reject(error);
});
return def.promise;
如果我有这样的服务:
app.factory('User', function($http, User) {
var User = function(data) {
angular.extend(this, data);
};
User.prototype.create = function() {
var user = this;
return $http.post(api, user.getProperties()).success(function(response) {
user.uid = response.data.uid;
}).error(function(response) {
});
};
User.get = function(id) {
return $http.get(url).success(function(response) {
return new User(response.data);
});
};
return User;
});
如何在控制器中获取在 get()
函数中创建的 User
?
目前我拥有的是:
app.controller('UserCtrl', function($scope, User) {
$scope.user = null;
User.get($routeParams.rid).success(function(u) {
$scope.user = new User(u.data);
});
});
问题是 UserCtrl
得到的是 api 响应,而不是工厂中 success()
返回的值。我更愿意在工厂中创建新用户,而不是将 api 响应传递给控制器。
我觉得你的 returns 有点乱。我个人会这样写
app.factory('User', function ($http) {
var user = {
new: function (data) {
return $http.post(api, data);
},
get: function (id) {
$http.get(url).success(function (response) {
return user.new(response.data);
});
}
};
return user;
});
然后从你的控制器里面..
app.controller('UserCtrl', function($scope, User) {
$scope.user = null;
User.get($routeParams.rid).success(function(u) {
$scope.user = u.data;
});
});
编辑:2015 年 5 月 5 日
我了解了 deferred anti-pattern while trying to answer this
所以我们可以避免使用$q.defer()
,使用下面的代码可以达到同样的效果。
服务
User.get = function(id) {
return $http.get(url).then(function(response) {
return new User(response.data);
});
};
控制器
User.get($routeParams.rid).then(function(u) {
$scope.user = u;
});
原回答如下:
我认为您正在寻找的是 $q
服务,它允许您对来自异步 $http
服务的响应进行一些 post 处理,然后 return 它作为对控制器的承诺。在此处查看文档 https://docs.angularjs.org/api/ng/service/$q
因此,在您的工厂中注入 $q
服务并更改您的 User.get
功能,如下所示。
User.get = function(id) {
var deferred = $q.defer();
$http.get(url).success(function(response) {
deferred.resolve(new User(response.data));
}).error(function(error) {
deferred.reject(error);
});
return deferred.promise;
};
然后在你的控制器中你可以做
User.get($routeParams.rid).then(function(u) {
$scope.user = u;
}, function(error) {
//log error
});
有类似的问题,当我将 'response.data' 传递给 def.resolve 时,它从控制器中抛出未定义。于是直接通过response就成功了
var def = $q.defer();
$http.get('http://localhost:3000/api/services')
.success(function (response) {
***def.resolve(response);***
})
.error(function (error) {
def.reject(error);
});
return def.promise;