我是Angular的新手,但不是编程。试图教老狗新技巧:)
我有一个textarea,用户输入要查找的字典单词列表。目前有3个地方通过$ http获取API并从API中获取响应。说我在textarea中有这些:
computer
fragment
teleport
它遍历textarea并运行" lookupWord()"对于每个单词。将所有3个API结果组合在一起,我生成自己的唯一ID,并在对象顶部包含单词。这样我就可以将结果放在一个表中,并使表行(tr)id成为我生成的唯一ID。有一个"视图"每行按钮,当它们点击它时,会弹出一个包含所有细节的模态。这个过程只是简单地匹配对象数组中的结果,特别是如果有重复的单词。
我的问题
我现在挂起,正在循环通过textarea并保持处理顺序。当他们单击开始按钮时,我想禁用表单上的textarea和复选框,因此在处理过程中不能更改任何内容。完成后,需要解锁表单并提醒用户完成表单。
我还没有禁用这些元素,但我试图让它说'#34;完成"在它循环并查找每个单词之后。它报告"完成"在一切都完成之前:(
以下是一些代码:
HTML
<textarea ng-model="wordlistTextarea" ng-list=" " ng-trim="false" class="form-control" id="wordsTextarea" placeholder="words to research..." rows="10"></textarea>
<input ng-model="checkboxSources.webster" type="checkbox" id="webster-api"> Merriam Webster (Dictionary API)
<input ng-model="checkboxSources.oxford" type="checkbox" id="oxford-api"> Oxford American College Dictionary (Google)
<input ng-model="checkboxSources.forvo" type="checkbox" id="forvo-api"> Forvo Pronunciation Dictionary
<button ng-disabled="!wordlistTextarea" ng-click="startProcessing()" class="btn btn-success" id="pronunciation-submit" preventDefault>Search</button>
JS
$scope.searchResults = []; // holds array of objects for later use
$scope.baseApiUri = 'http://apibase.com/api/here';
$scope.checkboxSources = {
webster : true,
oxford : true,
forvo : true
};
$scope.startProcessing = function() {
var promises = [];
angular.forEach($scope.wordlistTextarea, function(value, key){
//$scope.lookupWord(value.trim());
promises.push($scope.lookupWord(value.trim()));
});
$q.all(promises).then(function(results) {
console.dir(results);
})
.then(function(data) {
console.log('DONE!!');
});
};
$scope.lookupWord = function($word) {
Q.all([$scope.getWebster($word), $scope.getOxford($word), $scope.getForvo($word)])
.spread(function (resultWebster, resultOxford, resultForvo) {
var randomId = $scope.getRandomId();
var result = {
'word': $word,
'id': randomId,
'sources': {
'webster': resultWebster.data,
'oxford': resultOxford.data,
'forvo': resultForvo.data,
},
};
$scope.addToResults(result);
})
.done();
};
$scope.downloadPart = function(myUrl) {
return $http({
method: 'GET',
url: myUrl,
});
};
$scope.addToResults = function(data) {
console.log('Adding Result:');
console.dir(data);
$scope.searchResults.push(data);
};
// -- API SOURCES --
$scope.getWebster = function(word) {
if ( $scope.checkboxSources.webster == true ) {
var url = $scope.baseApiUri + '/dictionary?word=' + word;
return $scope.downloadPart(url);
} else {
return null;
}
};
$scope.getOxford = function(word) {
if ( $scope.checkboxSources.oxford == true ) {
var url = $scope.baseApiUri + '/oxford?word=' + word;
return $scope.downloadPart(url);
} else {
return null;
}
};
$scope.getForvo = function(word) {
if ( $scope.checkboxSources.forvo == true ) {
var url = $scope.baseApiUri + '/forvo?word=' + word;
return $scope.downloadPart(url);
} else {
return null;
}
};
概述
同样,我的问题是当我点击startProcessing
的按钮时,它需要先做东西(禁用表格),循环通过textarea并查找单词。完成后,我需要做更多的事情(比如表单上的启用元素,警告Done!等)。
此外,我想替换Angular附带的$ q中的Q
(我已经包含了库)。我使用了Q
,因为它有spread
。如您所见,我使用spread将结果专门放入对象中。我不知道我是否可以使用$q.all()
而使用$result[0], $result[1], etc
?
有任何问题,请告诉我。我写这篇文章的原因很快,因为我将采取孩子的伎俩或治疗:)
提前致谢!
PS:随意纠正我的坏角色,或者我应该如何做得更好(或正确)。这是学习和变得更好的唯一方法;)
答案 0 :(得分:1)
问题是promise数组实际上不是promises
的数组。
您的lookupWord
函数需要返回它创建的承诺,以便观察它。
只需为其创建的承诺添加return
。
$scope.lookupWord = function($word) {
return Q.all([$scope.getWebster($word), $scope.getOxford($word), $scope.getForvo($word)])
.spread(function (resultWebster, resultOxford, resultForvo) {
var randomId = $scope.getRandomId();
var result = {
'word': $word,
'id': randomId,
'sources': {
'webster': resultWebster.data,
'oxford': resultOxford.data,
'forvo': resultForvo.data,
},
};
$scope.addToResults(result);
})
.done();
};