如何将服务中的数据传递到我的控制器中?
How can I pass data from a service into my controller?
好吧,现在我正在摆弄 ionic 框架并同时学习 angularJS。我刚刚遇到 $q 和异步调用,但我似乎无法正确处理。我希望能够解析我已经使用 GetJsonSpecials
设置的 JSON 文件,然后将其传递给 GetData
,然后再将其传递给我的控制器 SpecialsCtrl
所以我可以将其附加到 $scope
。我知道我没有正确理解承诺,因为 SpecialService
中的所有内容都未定义。我可以从其他两个服务中完美地获取数据,但是当我尝试将它传递给 SpecialService
时,它似乎都崩溃了,这反过来在我的控制器中最终成为未定义的。也许我没有以正确的方式解决这个问题?做这种事情有什么最佳实践吗?
angular.module('starter.controllers', [])
.controller('SpecialsCtrl', function ($scope, SpecialService) {
$scope.specials = SpecialService.all();
console.log("Specials Controller: Got Data", $scope.specials);
})
//Create methods to access the specials inside the controller in which we inject this in
.factory('SpecialService', function (GetData) {
var specials = GetData.getSpecials();
console.log("DATAAAA: ", specials);
return {
// Return all specials
all: function () {
console.log("Inside return with specials: ", specials);
return specials;
},
getSpecialWithId : function (specialId) {
// Simple index lookup
return specials[i];
}
}
}
})
.factory('GetData', function(GetJsonSpecials) {
return {
getSpecials : function() {
GetJsonSpecials.retrieveData().then(function (data) {
console.log("Got the JSON data", data);
return data;
}, function (status) {
alert("Error getting specicals", status);
console.log("Error getting specicals", status);
});
}
}
})
//Asynchronously get the specials from the json file
.factory('GetJsonSpecials', function ($q, $http) {
return {
retrieveData : function() {
var deferred = $q.defer();
$http.get('js/specials.json').success(function (data, status) {
deferred.resolve(data);
}).error(function (status) {
deferred.reject(status);
console.log("Error in handling json!");
});
return deferred.promise;
}
}
})
我之所以过于复杂,是因为最后我希望能够将数据共享到另一个控制器,该控制器将在新视图中显示特定特价商品的属性。
.controller('DetailCtrl', function ($scope, $stateParams, JsonSpecials, $firebaseAuth) {
$scope.id = parseInt($stateParams.specialId);
$scope.special = JsonSpecials.getSpecialWithId($scope.id);
})
看来你把事情复杂化了一点。您无缘无故地在工厂周围传递数据。我认为这三个工厂可以合并为一个。也许尝试像..
index.html
<!DOCTYPE html>
<html ng-app="foobar">
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div ng-controller="SpecialsCtrl">
{{specials}}
</div>
<div ng-controller="AnotherController">
{{specials}}
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="script.js"></script>
</body>
</html>
script.js
angular.module('foobar', [])
.controller('SpecialsCtrl', function ($scope, JsonSpecials) {
JsonSpecials.retrieveData().then(function(data){
$scope.specials = data;
});
})
.controller('AnotherController', function ($scope, JsonSpecials) {
JsonSpecials.retrieveData().then(function(data){
$scope.specials = data;
});
})
//$http returns a promise anyway so you don't need $q
.factory('JsonSpecials', function ($http){
return {
retrieveData : function() {
return $http
.get('js/specials.json')
.error(function (status) {
console.log("Error in handling json!");
});
}
}
});
这里有一些问题。主要问题是 angularjs promises 是异步的,而您正试图以同步方式使用它们。
首先,您的 SpecialService
定义后有一个额外的 }
。
在你的 SpecialService
:
.factory('SpecialService', function (GetData) {
var specials = GetData.getSpecials();
这没什么,因为你的GetData.getSpecials()
return什么都没有。
如果您要将 GetData.getSepcials
修复为 return:
getSpecials : function() {
return GetJsonSpecials.retrieveData().then(function (data) {
console.log("Got the JSON data", data);
return data;
}, function (status) {
alert("Error getting specicals", status);
console.log("Error getting specicals", status);
});
}
然后回到 SpecialService
,您需要更改获取数据的方式。
var specials = GetData.getSpecials();
也不会给你你的数据。这将是一个承诺,因为它是异步的。所以需要
GetData.getSpecials().then(function(data) {
return data;
});
此外,正如 Matt 所指出的,在您的 retrieveData
定义中,您正在创建一个不必要的承诺。所以
retrieveData : function() {
var deferred = $q.defer();
$http.get('js/specials.json').success(function (data, status) {
deferred.resolve(data);
}).error(function (status) {
deferred.reject(status);
console.log("Error in handling json!");
});
return deferred.promise;
}
等同于:
retrieveData : function() {
return $http.get('js/specials.json').error(function (status) {
console.log("Error in handling json!");
return status;
});
}
好吧,现在我正在摆弄 ionic 框架并同时学习 angularJS。我刚刚遇到 $q 和异步调用,但我似乎无法正确处理。我希望能够解析我已经使用 GetJsonSpecials
设置的 JSON 文件,然后将其传递给 GetData
,然后再将其传递给我的控制器 SpecialsCtrl
所以我可以将其附加到 $scope
。我知道我没有正确理解承诺,因为 SpecialService
中的所有内容都未定义。我可以从其他两个服务中完美地获取数据,但是当我尝试将它传递给 SpecialService
时,它似乎都崩溃了,这反过来在我的控制器中最终成为未定义的。也许我没有以正确的方式解决这个问题?做这种事情有什么最佳实践吗?
angular.module('starter.controllers', [])
.controller('SpecialsCtrl', function ($scope, SpecialService) {
$scope.specials = SpecialService.all();
console.log("Specials Controller: Got Data", $scope.specials);
})
//Create methods to access the specials inside the controller in which we inject this in
.factory('SpecialService', function (GetData) {
var specials = GetData.getSpecials();
console.log("DATAAAA: ", specials);
return {
// Return all specials
all: function () {
console.log("Inside return with specials: ", specials);
return specials;
},
getSpecialWithId : function (specialId) {
// Simple index lookup
return specials[i];
}
}
}
})
.factory('GetData', function(GetJsonSpecials) {
return {
getSpecials : function() {
GetJsonSpecials.retrieveData().then(function (data) {
console.log("Got the JSON data", data);
return data;
}, function (status) {
alert("Error getting specicals", status);
console.log("Error getting specicals", status);
});
}
}
})
//Asynchronously get the specials from the json file
.factory('GetJsonSpecials', function ($q, $http) {
return {
retrieveData : function() {
var deferred = $q.defer();
$http.get('js/specials.json').success(function (data, status) {
deferred.resolve(data);
}).error(function (status) {
deferred.reject(status);
console.log("Error in handling json!");
});
return deferred.promise;
}
}
})
我之所以过于复杂,是因为最后我希望能够将数据共享到另一个控制器,该控制器将在新视图中显示特定特价商品的属性。
.controller('DetailCtrl', function ($scope, $stateParams, JsonSpecials, $firebaseAuth) {
$scope.id = parseInt($stateParams.specialId);
$scope.special = JsonSpecials.getSpecialWithId($scope.id);
})
看来你把事情复杂化了一点。您无缘无故地在工厂周围传递数据。我认为这三个工厂可以合并为一个。也许尝试像..
index.html
<!DOCTYPE html>
<html ng-app="foobar">
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div ng-controller="SpecialsCtrl">
{{specials}}
</div>
<div ng-controller="AnotherController">
{{specials}}
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="script.js"></script>
</body>
</html>
script.js
angular.module('foobar', [])
.controller('SpecialsCtrl', function ($scope, JsonSpecials) {
JsonSpecials.retrieveData().then(function(data){
$scope.specials = data;
});
})
.controller('AnotherController', function ($scope, JsonSpecials) {
JsonSpecials.retrieveData().then(function(data){
$scope.specials = data;
});
})
//$http returns a promise anyway so you don't need $q
.factory('JsonSpecials', function ($http){
return {
retrieveData : function() {
return $http
.get('js/specials.json')
.error(function (status) {
console.log("Error in handling json!");
});
}
}
});
这里有一些问题。主要问题是 angularjs promises 是异步的,而您正试图以同步方式使用它们。
首先,您的 SpecialService
定义后有一个额外的 }
。
在你的 SpecialService
:
.factory('SpecialService', function (GetData) {
var specials = GetData.getSpecials();
这没什么,因为你的GetData.getSpecials()
return什么都没有。
如果您要将 GetData.getSepcials
修复为 return:
getSpecials : function() {
return GetJsonSpecials.retrieveData().then(function (data) {
console.log("Got the JSON data", data);
return data;
}, function (status) {
alert("Error getting specicals", status);
console.log("Error getting specicals", status);
});
}
然后回到 SpecialService
,您需要更改获取数据的方式。
var specials = GetData.getSpecials();
也不会给你你的数据。这将是一个承诺,因为它是异步的。所以需要
GetData.getSpecials().then(function(data) {
return data;
});
此外,正如 Matt 所指出的,在您的 retrieveData
定义中,您正在创建一个不必要的承诺。所以
retrieveData : function() {
var deferred = $q.defer();
$http.get('js/specials.json').success(function (data, status) {
deferred.resolve(data);
}).error(function (status) {
deferred.reject(status);
console.log("Error in handling json!");
});
return deferred.promise;
}
等同于:
retrieveData : function() {
return $http.get('js/specials.json').error(function (status) {
console.log("Error in handling json!");
return status;
});
}