2017-11-24 5 views
1

ページを最初に読み込んだときに式の自動更新を行う方法を理解するのに問題があります。 JSONオブジェクトを取得して$scope.stocksに割り当てるサービスを使用しています。 $watchを使用して、日付スライダー値が更新されるたびに動的に$scope.thisStockを更新しています。うまくいきます。ただし、ページが最初に読み込まれるとき、$scope.thisStockは未定義です。私はこれらの問題を解決するための最高の、最もエレガントな方法は何ページの読み込み時に式が自動更新されないのはなぜですか?

$scope.stocks is undefined error message

:さらに、私は、コンソールでの迷惑なエラーメッセージを取得していますか?非同期呼び出しが解決される前にコントローラが$scope.stocksを読み込めないようにするにはどうすればいいですか?角度スライダを最初に動かすことなく、できるだけ早くAngularが$scope.thisStockをロードするように強制するにはどうすればいいですか?ここで

は私のコントローラです:

sim.controller("StocksCtrl", ['$scope', 'StockService', 'DateService', 
    function($scope, StockService, DateService) { 

    $scope.init = function() { 
     $scope.getStocks(); 
    }; 

    $scope.getStocks = function() { 
     StockService.all().then(function(stocks){ 
     $scope.stocks = stocks; 
     }); 
    }; 

    $scope.$watch(function() {return DateService.getCurrentDate()}, function(newValue) { 
     $scope.currentDate = newValue; 
     $scope.reformatCurrentDate(); 
    }); 

    $scope.reformatCurrentDate = function() { 
     var arr = $scope.currentDate.split("/"); 
     if (arr[1].length === 1) { 
     arr[1] = "0" + arr[1]; 
     } 
     $scope.reformattedCurrentDate = arr[2] + "-" + arr[0] + "-" + arr[1]; 
    }; 

    $scope.$watch('reformattedCurrentDate', function() { 
     $scope.thisStock = $scope.stocks[$scope.reformattedCurrentDate]["price"]; 
    }); 

}]); 

そしてここでは、HTMLインデックスの関連セクションです:変化検出がreformattedCurrentDate変数に対して発生したときに

{{thisStock | currency}} 

答えて

0

$watch機能が実行されます。しかし、時計機能は、$scope.stocksが非同期呼び出しから値を取得する前に呼び出されます。ので、単に条件を入れて$scope.stocksがヌルでないことを確認してください。

$scope.$watch('reformattedCurrentDate', function() { 
    if($scope.stocks) { 
     $scope.thisStock = $scope.stocks[$scope.reformattedCurrentDate]["price"]; 
    } 
}); 
0

最初のロードでは、Angularは$watchイベントを1回発射します。 $scope.stocksがまだ配列ではないため、あなたのアプリは非同期要求後に変数$scope.stocksを定義しますが、それ以前に時計機能が起動され、$scope.stocks[$scope.reformattedCurrentDate]["price"]で未定義になります。

$scope.stocksは、必要な値があるかどうかわからないうちに時計機能内に$scope.stocks != null && $scope.stocks.length > 0などの空の配列がないかどうかを確認する必要があります。バックエンドの応答が失敗し、応答にあなたの配列が含まれていない場合も考慮してください。

オプションで、古い値と新しい値が等しい場合と比較して、この最初の時計の実行を検出できます。

私はこれがあなたのデータにアクセスするための可能な限り早い場所であり、あなたは要求が成功したことを確認することができますよう、あなたの要求応答内$scope.stocksと一緒にそれを設定することをお勧め$scope.thisStockの初期値を設定することについて:

$scope.getStocks = function() { 
     StockService.all().then(function(stocks){ 
     $scope.stocks = stocks; 
     $scope.thisStocks = <FIRST_AVAILABLE_DATE> 
     }); 
    }; 
0

これは

$scope.reformattedCurrentDate = arr[2] + "-" + arr[0] + "-" + arr[1]; 

$ scope.reformattedCurrentDateの変更唯一の場所である場合、あなたはいけない関数呼び出しの数がとにかく右、不要な増加を見て必要があります。

$scope.reformattedCurrentDate = arr[2] + "-" + arr[0] + "-" + arr[1]; 
$scope.thisStock = $scope.stocks[$scope.reformattedCurrentDate]["price"]; 

これが実行され、時計を取り外すことができます。それから、誰もが$ scope.thisStockを初期化し、使用量$ scope.stockをチェックするか、コントローラの開始時に何らかのデフォルト値で初期化する必要があると言っています。

関連する問題