我在AngularJS中编写此模块,使用ParseServer数据库存储和检索我的对象。
初始化模块时,我想查询数据库并将列表中保存的所有句子显示为列表。
controller.js:
Parse.initialize("[APPID]", "[MASTERKEY]");
Parse.serverURL = 'http://localhost:1337/parse';
angular.module('CorrectionModule', ['ngMaterial', 'ngSanitize'])
.controller('SentenceCorrectionCtrl', ['$rootScope', '$mdDialog', '$scope',
function($rootScope, $mdDialog, $scope) {
$rootScope.sentences = [];
var obj = Parse.Object.extend("Sentence");
var queryObject = new Parse.Query(obj);
queryObject.find({
success: function(result) {
for (var i = 0; i < result.length; i++) {
$rootScope.sentences.push(result[i]);
}
console.log('Found ' + $rootScope.sentences.length + ' objects');
},
error: function(error) {
console.log('Error ' + error.code + ': ' + error.message);
}
});
$rootScope.currentUser = 'Student';
$scope.switchUser = function() {
if ($rootScope.currentUser == 'Teacher') {
$rootScope.currentUser = 'Student'
} else if ($rootScope.currentUser == 'Student') {
$rootScope.currentUser = 'Teacher';
}
}
$scope.addSentence = function() {
var parentEl = angular.element(document.body);
$mdDialog.show({
parent: parentEl,
templateUrl: "student-add-sentence.tmpl.html",
controller: StudentAddController
});
function StudentAddController($scope, $mdDialog, $rootScope) {
// $scope.user = $rootScope.currentUser;
$scope.sentence = null;
$scope.error = false;
// SentenceObject = new Parse.Object('Sentence');
$scope.saveSentence = function() {
if (!$scope.sentence){
$scope.error = 'Please add a sentence';
} else {
$scope.error = false;
}
if (!$scope.error){
// SentenceObject.set("sentence", $scope.sentence);
// SentenceObject.save(null, {
// success: function(parseObject){
// console.log('Saved[' + SentenceObject.id + ']: ' + $scope.sentence);
// $rootScope.sentences.push($scope.sentence);
// $scope.sentence = null;
// },
// error: function(parseObject, error) {
// console.log('Error code: ' + error);
// }
// });
$rootScope.sentences.push($scope.sentence);
$mdDialog.hide();
}
}
$scope.cancel = function(){
$mdDialog.hide();
}
}
}
}
]);
的index.html:
<html>
<title></title>
<head>
<!-- Angular Material CSS now available via Google CDN; version 1.0.7 used here -->
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/0.11.2/angular-material.min.css">
</head>
<body ng-app="CorrectionModule" ng-controller="SentenceCorrectionCtrl" layout="column">
<!-- Container #1 (see wireframe) -->
<md-toolbar layout="row">
<h1>Correction</h1>
</md-toolbar>
<div>
<md-button ng-click="addSentence()" ng-if="currentUser=='Student'">Add Sentence</md-button>
<!-- <md-button ng-click="" ng-if="currentUser=='Teacher'"> -->
<br/>
</div>
<ul>
<li ng-repeat="x in sentences">{{ x }}</li>
</ul>
<md-button ng-click="switchUser()">Logged in as {{ currentUser }}</md-button>
<!-- Utilities script -->
<script type="text/javascript" src="http://www.parsecdn.com/js/parse-latest.js"></script>
<!-- Angular Material Dependencies -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-aria.min.js"></script>
<!-- Angular Material Javascript now available via Google CDN; version 1.0.7 used here -->
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.7/angular-material.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-sanitize.js"></script>
<!-- Custom controllers for different views -->
<script src="controller.js"></script>
</body>
</html>
问题在于,当我运行代码时,它不会显示任何内容,直到我按下调用对话框窗口的按钮。
查询与其余代码异步运行,但我需要它运行,然后其余代码可以继续。
我已经搜索了一些其他解决方案,涉及创建一个调用结果的显式函数,但结果相同。
提前感谢您对此的帮助。
答案 0 :(得分:2)
$q
1 - 一种服务,可以帮助您异步运行函数,并在完成处理后使用它们的返回值(或异常)。< /强>
要等待异步结果返回,在执行其余代码之前,将queryObject.find
调用转换为$q
service承诺,然后将链转换为该承诺。< / p>
创建承诺
//Created Deferred Object
var findDeferred = $q.defer();
//Resolve Deferred Object;
queryObject.find({
success: function(result) {
findDeferred.resolve(result);
},
error: function(error) {
findDeferred.reject(error);
}
});
//Create promise from Deferred Object
var findPromise = findDeferred.promise;
承诺链
//Create derived promise
var derivedFindPromise = findPromise.then( function onSuccess(result) {
var sentences = [];
for (var i = 0; i < result.length; i++) {
sentences.push(result[i]);
}
console.log('Found ' + sentences.length + ' objects');
//return to chain data
return sentences;
}).catch( function onReject(error) {
console.log('Error ' + error.code + ': ' + error.message);
//throw to chain error
throw error;
});
//Use derived promise
derivedFindPromise.then(function onSuccess2(sentences) {
$scope.sentences = sentences;
//Call subsequent functions here
});
因为调用promise的
.then
方法会返回一个新的派生promise,所以很容易创建一个promise链。可以创建任意长度的链,并且由于可以使用另一个承诺(将进一步推迟其解析)来解决承诺,因此可以在链中的任何点暂停/推迟承诺的解析。这使得实现强大的API成为可能。
答案 1 :(得分:-1)
如果将其余代码包装在单个函数中,则可以从成功内部调用该函数。这有什么原因不起作用吗?
或者,您可以使用布尔变量来标记代码的其余部分是否应该运行。然后使用$ interval来测试变量,直到它准备好。这是一个很好的例子。
var isReady = false;
...
queryObject.find({
success: function() {
isReady = true;
},
error: function() {
...
});
...
var interval = $interval(function() {
if (isReady) {
// call the code you want to execute
// after the async operation is finished
}
}, 500); // how often you want to check if the operation is finished