2016-10-31 13 views
0

私はAngularを初めて使っていますが、プログラミングはしていません。古い犬に新しいトリックを教えようとしています:)角度、約束、テキストエリアでのforeach、処理順序の維持

私は、ユーザが検索する辞書の単語のリストを入力するテキストエリアを持っています。現在、$ http経由でAPIを使用する場所は3つあり、APIからの応答を取得します。私は、テキストエリアにこれらを持っていると言う:

computer 
fragment 
teleport 

それはテキストエリアをループし、各単語のための「lookupWordを()」が実行されます。すべての3つのAPIの結果が結合され、私は自分の一意のIDを生成するだけでなく、オブジェクトの上部に単語を含めます。これは結果をテーブルに入れて、テーブル行の(tr)idを私が生成した一意のIDにすることができるようにするためです。各行に「表示」ボタンがあり、クリックするとすべての詳細が表示されます。このプロセスでは、特に重複する単語がある場合は、オブジェクトの配列内の結果を一致させるのが非常に簡単になります。

私の問題

私は、今のハングアップのtextareaをループして処理順序を保っています。彼らはスタートボタンをクリックすると、フォームのテキストエリアとチェックボックスを無効にしたいので、処理の途中で何も変更することはできません。それが完了したら、フォームのロックを解除し、ユーザーに警告します。

まだ要素を無効にしているわけではありませんが、ループして各単語を参照した後、「完了」と言うようにしています。

<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; 
    } 
}; 

概要再び

HTML、:すべてが実際にここで

はいくつかのコードです:(行われる前に、それは "完了" レポート私の問題はのボタンをクリックしたときです、それは最初に(フォームを無効にする)、テキストエリアをループし、単語を参照するものを行う必要があります。完了したら、私はより多くのものを実行する必要があります(フォーム上の要素を有効にする、完了を警告するなど)。

さらに、Angularに含まれている$ qのQ(ライブラリが含まれています)を置き換えたいとします。 spreadがあるので、私はQを使用しました。ご覧のとおり、結果をオブジェクトに具体的に入れるためにspreadを使用します。代わりに$q.all()を使用でき、$result[0], $result[1], etcを使用できるかどうかわかりませんか?

質問がありましたら、お知らせください。私は子供たちをトリックやトリートメントに乗せようとしているので、これを素早く書きました:)

ありがとうございました!

PS:悪い角度で私を修正してもどうかやってみたり、どうすればいいですか(正しく)。

答えて

1

プロミスアレイは実際には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(); 
}; 
+0

私はテキストエリアをループしていますが、forEachはまだコードの残りの部分に移動する前に終了していません。私はそれが結果があるまで(lookupWord())それが終了したらページをロックすることができますので、それを停止する必要があります。 –

+0

私は実際にそれを働かせました。私は余裕を持って解決策を更新します。ありがとうございました。 –