AngularJS Ctrl As 服务语法
AngularJS Ctrl As Syntax with Services
我正在迁移我的 Angular 1.x 代码以使用更新、更优选的语法,避免使用 $scope 和使用控制器作为语法。不过,我在从服务获取数据时遇到问题。
这是我的例子:
var myApp = angular.module('myApp', []);
myApp.controller('MainCtrl', ['$http', '$location', 'userService',
function($http, $location, userService) {
this.name = 'John Doe';
// this.userData = {
// }
this.userData = userService.async().then(function(d) {
return d;
});
console.log(this.userData);
}
]);
myApp.service('userService', function($http) {
var userService = {
async: function() {
// $http returns a promise, which has a then function, which also returns a promise
var promise = $http.get('https://jsonplaceholder.typicode.com/users').then(function(response) {
// The then function here is an opportunity to modify the response
// console.log(response);
// The return value gets picked up by the then in the controller.
return response.data;
});
// Return the promise to the controller
return promise;
}
};
return userService;
});
<body ng-app="myApp">
<div id="ctrl-as-exmpl" ng-controller="MainCtrl as mainctrl">
<h1>Phone Numbers for {{mainctrl.name}}</h1>
<button ng-click="">newest</button>
<p>{{mainctrl.userData}}</p>
<ul>
<li ng-repeat="users in mainctrl.userData">{{users.phone}} -- {{users.email}}</li>
</ul>
</div>
</body>
我遇到的这个问题是,从 userService.async 返回的数据是一个我似乎无法向下钻取以获取数据的对象,因为该数据是 $ 的子项$state,在视图中好像不能用。
如果这不是在 Controller As/$scope-less 语法中使用服务的正确方法,那么正确的方法是什么?
this.userData = userService.async().then(function(d) {
return d;
});
在这段代码中 this.userData
实际上被定义为一个承诺。如果您想要正在 returned 的数据,您需要使用 .then
function
中的 d
参数,如下所示:
userService.async().then(function(d){
this.userData = d;
//a console.log() here would determine if you are getting the data you want.
});
编辑
我刚刚在您的服务中注意到您已经在响应对象上使用了 .data
。
老实说,我给你最好的建议就是 return 来自你服务内部的 http.get()
调用的承诺,如下所示:
myApp.service('userService', function($http) {
var userService = {
async: function() {
return $http.get('https://jsonplaceholder.typicode.com/users');
}
};
return userService;
});
然后您可以使用类似这样的方法来捕获和利用响应数据:
userService.async().then(function(response){
this.userData = response.data;
);
这可能是一个更简洁的解决方案
您错过了 promise 的一个重要部分 - 当您 return 来自 promise 的一个值时,您 return 一个将解析为该值的新 promise。
当前将数据return从承诺设置为控制器中局部变量的方法是这样的:
myApp.controller('MainCtrl', ['$http', '$location', 'userService',
function($http, $location, userService) {
this.name = 'John Doe';
userService.async().then(function(d) {
this.userData = d;
});
}
]);
但是现在您因为 this
的范围而陷入困境,因此通常为控制器 this
范围使用 "placeholder" 变量。
myApp.controller('MainCtrl', ['$http', '$location', 'userService',
function($http, $location, userService) {
var $ctrl = this; // Use $ctrl instead of this when you want to address the controller instance
$ctrl.name = 'John Doe';
userService.async().then(function(d) {
$ctrl.userData = d;
});
}
]);
我正在迁移我的 Angular 1.x 代码以使用更新、更优选的语法,避免使用 $scope 和使用控制器作为语法。不过,我在从服务获取数据时遇到问题。
这是我的例子:
var myApp = angular.module('myApp', []);
myApp.controller('MainCtrl', ['$http', '$location', 'userService',
function($http, $location, userService) {
this.name = 'John Doe';
// this.userData = {
// }
this.userData = userService.async().then(function(d) {
return d;
});
console.log(this.userData);
}
]);
myApp.service('userService', function($http) {
var userService = {
async: function() {
// $http returns a promise, which has a then function, which also returns a promise
var promise = $http.get('https://jsonplaceholder.typicode.com/users').then(function(response) {
// The then function here is an opportunity to modify the response
// console.log(response);
// The return value gets picked up by the then in the controller.
return response.data;
});
// Return the promise to the controller
return promise;
}
};
return userService;
});
<body ng-app="myApp">
<div id="ctrl-as-exmpl" ng-controller="MainCtrl as mainctrl">
<h1>Phone Numbers for {{mainctrl.name}}</h1>
<button ng-click="">newest</button>
<p>{{mainctrl.userData}}</p>
<ul>
<li ng-repeat="users in mainctrl.userData">{{users.phone}} -- {{users.email}}</li>
</ul>
</div>
</body>
我遇到的这个问题是,从 userService.async 返回的数据是一个我似乎无法向下钻取以获取数据的对象,因为该数据是 $ 的子项$state,在视图中好像不能用。
如果这不是在 Controller As/$scope-less 语法中使用服务的正确方法,那么正确的方法是什么?
this.userData = userService.async().then(function(d) {
return d;
});
在这段代码中 this.userData
实际上被定义为一个承诺。如果您想要正在 returned 的数据,您需要使用 .then
function
中的 d
参数,如下所示:
userService.async().then(function(d){
this.userData = d;
//a console.log() here would determine if you are getting the data you want.
});
编辑
我刚刚在您的服务中注意到您已经在响应对象上使用了 .data
。
老实说,我给你最好的建议就是 return 来自你服务内部的 http.get()
调用的承诺,如下所示:
myApp.service('userService', function($http) {
var userService = {
async: function() {
return $http.get('https://jsonplaceholder.typicode.com/users');
}
};
return userService;
});
然后您可以使用类似这样的方法来捕获和利用响应数据:
userService.async().then(function(response){
this.userData = response.data;
);
这可能是一个更简洁的解决方案
您错过了 promise 的一个重要部分 - 当您 return 来自 promise 的一个值时,您 return 一个将解析为该值的新 promise。
当前将数据return从承诺设置为控制器中局部变量的方法是这样的:
myApp.controller('MainCtrl', ['$http', '$location', 'userService',
function($http, $location, userService) {
this.name = 'John Doe';
userService.async().then(function(d) {
this.userData = d;
});
}
]);
但是现在您因为 this
的范围而陷入困境,因此通常为控制器 this
范围使用 "placeholder" 变量。
myApp.controller('MainCtrl', ['$http', '$location', 'userService',
function($http, $location, userService) {
var $ctrl = this; // Use $ctrl instead of this when you want to address the controller instance
$ctrl.name = 'John Doe';
userService.async().then(function(d) {
$ctrl.userData = d;
});
}
]);