Angular,Promises,foreach in textarea,并保持处理顺序

时间:2016-10-31 21:22:27

标签: javascript html angularjs

我是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="&#10;" 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:随意纠正我的坏角色,或者我应该如何做得更好(或正确)。这是学习和变得更好的唯一方法;)

1 个答案:

答案 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();
};