我有以下控制器:
Sponsors.$inject = [];
function Sponsors() {
var service = {
all: all,
allServer: allServer,
allLocal: allLocal,
get: get,
getTimeStamp: getTimeStamp
};
return service;
function all($http) {
var timeDifference = (Date.now() - this.getTimeStamp());
if (timeDifference < 600000) {
return this.allLocal();
}
else {
return this.allServer($http);
}
}
function allServer($http) {
return $http.get("http://dream16backend.azurewebsites.net/api/dream16/sponsors")
.then(function (resp) {
//Set localstorage, create timestamp and return the data
window.localStorage.setItem('sponsors', resp.data);
window.localStorage.setItem('sponsorsTimeStamp', Date.now());
var bla = JSON.parse(window.localStorage.getItem('sponsors'));
return bla;
}, function(err) {
console.log('ERR', err);
});
}
function allLocal() {
return JSON.parse(window.localStorage.getItem('sponsors'));
}
function get(adressId) {
for (var i = 0; i < sponsors.length; i++) {
if (sponsors[i].id === parseInt(sponsorId)) {
return sponsors[i];
}
}
return null;
}
function getTimeStamp() {
return window.localStorage.getItem('sponsorsTimeStamp');
}
}
使用&#34;然后&#34;是因为我收到了一个异步对象。但是,我现在也可以通过以下服务接收同步对象: (功能(){ 角 .module(&#39; sponsors.services&#39;,[]) .factory(&#39;赞助商&#39;,赞助商);
Sponsors.all(...).then is not a function
})();
这样只有异步调用(函数allServer)才能工作,但同步失败,因为:else {
this.allServer($http).then(function (data) {
return data;
})
}
.controller('SponsorsCtrl', function ($scope, Sponsors, $http) {
$scope.$on('$ionicView.enter', function () {
$scope.sponsors = Sponsors.all($http);
var check = "check";
});
})
控制器看起来像:
public class JavaFXApplication7 extends Application {
@Override
public void start(Stage primaryStage) {
ComboBox<Person> cb = new ComboBox();
cb.setCellFactory(column -> new ListCell<Person>() {
private HBox graphic = new HBox();
private Label label1 = new Label() ;
private Label label2 = new Label(" || ");
private Label label3 = new Label();
{
graphic.getChildren().addAll(label1, label2, label3);
}
@Override
public void updateItem(Person person, boolean empty) {
if (person == null || empty) {
setGraphic(null);
} else {
label1.setText(person.firstName.get());
label3.setText(person.email.get());
setGraphic(graphic);
}
}
});
ObservableList<Person> items = FXCollections.observableArrayList();
Person p = new Person();
p.email.set("foo@bar.com");
p.firstName.set("Tony");
p.lastName.set("Stark");
p.phone.set("(555) 555-1212");
items.add(p);
Person p2 = new Person();
p2.email.set("foo@bar.com");
p2.firstName.set("Bruce");
p2.lastName.set("Wayne");
p2.phone.set("(444) 444-1212");
items.add(p2);
cb.setItems(items);
StackPane root = new StackPane();
root.getChildren().add(cb);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
public class Person {
StringProperty firstName = new SimpleStringProperty();
StringProperty lastName = new SimpleStringProperty();
StringProperty phone = new SimpleStringProperty();
StringProperty email = new SimpleStringProperty();
@Override
public String toString () {
return firstName.get() + " " + lastName.get();
}
}
}
我确认调用本身正在运行(通过测试变量&#34; bla&#34;)。我还看到控制器运行的控制器var check =&#34; check&#34 ;;在运行异步代码之前。我在这里做错了什么?
答案 0 :(得分:1)
好的......所以你需要为Sponsors.all()
的两个实例返回一个承诺,因为一个实例已经返回$http
承诺。
在服务中注入$q
,以便allLocal()
也会返回一个承诺。
function allLocal() {
return $q.resolve(JSON.parse(window.localStorage.getItem('sponsors')));
}
在控制器中,您需要使用then()
$scope.$on('$ionicView.enter', function () {
Sponsors.all($http).then(function(data){
$scope.sponsors = data;
});
var check = "check";
});
正如上面的评论中所提到的,没有必要在控制器中注入$http
并将其传递给服务,只需在实际需要的地方注入$http
更简单
答案 1 :(得分:1)
我建议您使用以下解决方案。在这两种情况下都返回“Promise”对象。对于allLocal
函数,它将如下所示:
function allLocal() {
var deferred = $q.defer();
deferred.resolve(JSON.parse(window.localStorage.getItem('sponsors')));
return deferred.promise;
}
所以现在你可以在两种情况下使用.then
- sync和async
答案 2 :(得分:1)
我建议将$ http服务注入您的服务中...... I.e。
.factory('MyService', function ($http, $timeout,$q) {
var service = {
all: all,
allServer: allServer,
allLocal: allLocal,
get: get,
getTimeStamp: getTimeStamp
};
return service;
function all() {
var timeDifference = (Date.now() - this.getTimeStamp());
if (timeDifference < 600000) {
return this.allLocal();
}
else {
return this.allServer($http);
}
}
function allServer() {
return $http.get("http://dream16backend.azurewebsites.net/api/dream16/sponsors")
.then(function (resp) {
//Set localstorage, create timestamp and return the data
window.localStorage.setItem('sponsors', resp.data);
window.localStorage.setItem('sponsorsTimeStamp', Date.now());
var bla = JSON.parse(window.localStorage.getItem('sponsors'));
return bla;
}, function(err) {
console.log('ERR', err);
});
}
function allLocal() {
var dfd = $q.defer(); //create a deferred object
$timeout(function(){
var localResponse = JSON.parse(window.localStorage.getItem('sponsors'));;
dfd.resolve(localResponse); //resolve the localObject
});
return dfd.promise; //return the promise object so controller gets the .then function
}
function get(adressId) {
for (var i = 0; i < sponsors.length; i++) {
if (sponsors[i].id === parseInt(sponsorId)) {
return sponsors[i];
}
}
return null;
}
function getTimeStamp() {
return window.localStorage.getItem('sponsorsTimeStamp');
}
})
答案 3 :(得分:0)
如果您正在处理可能会或可能不会返回承诺的服务,您可以使用$q.when(...)
来包装该API调用,并让$q
处理其余的调用。
在你的情况下,你所要做的就是像$q.when(Sponsors.all($http))
一样包装你的服务API,并将它作为任何常规的承诺使用。
结帐https://github.com/kriskowal/q/wiki/API-Reference#promise-methods。