2016-12-19 15 views
3

私はAngularを初めて使用しています。私はコンポーネント(1.6)を使用しようとしています。親では、$http.getがサービスからデータを取得し、応答を$scope変数に割り当てます。そのスコープ変数は、一方向バインディング<を使用して子コンポーネントに渡されます。 JavaScriptでは、渡された変数に警告すると「未定義」になりますが、子のHTMLテンプレートに変数が表示されます。競合状態が起こっているように、サービスからのデータがロードされるまで待つように指示する方法はわかりません。私の子コンポーネントで

<thermometer baseline="baseline"></thermometer> 

:私の親HTMLテンプレートで

(function (angular) { 
    'use strict'; 
    $http.get("http://localhost:52422/api/PayOffYourCc") 
    .then(function mySucces(response) { 
     $scope.baseline = response.data; 

    } 
    , 
    function myError(respone) { 
     $scope.baseline = response.statusText; 

    } 
    ); 
})(window.angular); 

:私の子供のHTMLテンプレートで

(function (angular) { 
    'use strict'; 

    function drawChart(baselineVal) { 
     alert(baselineVal); 
    } 

    function ThermometerController($scope) { 
     var ctrl = this; 
     ctrl.$onInit = function() { 
      drawChart(ctrl.baseline); 
     }; 


    } 

    angular.module('payOffYourCcApp').component('thermometer', { 
     templateUrl: '../PayOffYourCC/partials/thermometer.html', 
     transclude: true, 
     controller: ThermometerController, 
     bindings: { 
      baseline: '<' 
     } 
    }); 
})(window.angular); 

私parent.jsで

<div> 
    baseline:{{$ctrl.baseline}} 
</div> 

htmlでは{{$ctrl.baseline}}が表示されますが、.jsで警告するとundefinedとなります。何故ですか?どうすれば{{$ctrl.baseline}}がjavascriptがロードされる前に有効範囲に入っていることを確認できますか?角度成分で

+0

httpコールバック関数が完了し、値がベースラインに割り当てられると、それに応じてビューを更新するダイジェストサイクルがトリガーされます。アラート操作は同期して行われますが、HTTP操作の前にも完了するチャンスがあります – IAmDranged

+0

すべてのソリューションをありがとうございます。しかし、私は今それをはるかに良く理解していますが、私はreact.jsを行ってしまいました。私はまだhttpコールバックと競争条件に問題がありますが、私はどのように乗っているかを教えてあげます。 –

+0

実際、Reactには他の同様の問題がありました。それはコンポーネントのライフサイクルに関係します。私は、Angularを使用することに戻りました - 下の答えのおかげで。 –

答えて

1

$onChangesライフサイクルフックを使用します。

function ThermometerController($scope) { 
    var ctrl = this; 
    /* REPLACE THIS 
    ctrl.$onInit = function() { 
     drawChart(ctrl.baseline); 
    }; */ 
    // WITH THIS 
    ctrl.$onChanges = function (changesObj) { 
     if (changesObj.baseline && changesObj.baseline.currentValue) { 
      drawChart(changesObj.baseline.currentValue); 
     }; 
    }; 
} 

コントローラは、データをサーバから来るのを待つ必要があります。 $ onChangesライフサイクルフックを使用すると、データが利用可能になったときにdrawChart関数が呼び出され、後続の更新で呼び出されます。

詳細については、AngularJS Comprehensive Directive API Reference - Life-Cycle Hooksを参照してください。

+0

ありがとうございました。これはうまくいった。 –

0

は、あなたがすべき戻って、親の子から特権通信はそれが非常に安い(&

あなたは親から子へと通信することができますが、それはより高価である結合(=ことができますので、 )。
私はあなたにそれを行う方法の例を挙げます。
これはテストされていない解決策ですが、あなたはその考えを持っているはずです。

あなたがデータを送信するために子供のAPIを持っているあなたの親を変更する必要があります。

JS親:

(function (angular) { 
    'use strict'; 
    $http.get("http://localhost:52422/api/PayOffYourCc") 
    .then(function mySucces(response) { 
     $scope.baseline = response.data; 
     $ctrl.apiChild.transmit(response.data); 
    } 
    , 
    function myError(respone) { 
     $scope.baseline = response.statusText; 
    } 
    ); 
})(window.angular); 

HTMLの親:

<thermometer api="$ctrl.apiChild"></thermometer> 

機能を持っているあなたの子供を変更親からデータを受け取り、バインディングを"="に変更する:

JS子供:

(function (angular) { 

'use strict'; 

function drawChart(baselineVal) { 
    alert(baselineVal); 
} 

function ThermometerController($scope) { 
    var ctrl = this; 
    ctrl.$onInit = function() { 
     drawChart(ctrl.baseline); 
     ctrl.api = {}; 
     ctrl.api.transmit = ctrl.transmitData; 
    }; 

    this.transmitData = function transmitData(data){ 
     // here you get the data from the parent to the child 
    } 

} 

angular.module('payOffYourCcApp').component('thermometer', { 
    templateUrl: '../PayOffYourCC/partials/thermometer.html', 
    transclude: true, 
    controller: ThermometerController, 
    bindings: { 
     api : '=' 
    } 
}); 
})(window.angular); 
0

これは、$ HTTPリクエストが非同期であるという事実の結果です。子コンポーネントが初期化したときに発生する警告は、undefinedを出力します。そのインスタンスでは、データを取得している$ http要求はまだ返されていません。ただし、>バインディングを使用しているため、リクエストが解決されるとすぐに子コンポーネントのテンプレートが正しい値で更新されるため、実際にテンプレートにundefinedが表示されることはありません。実際、私は角度が未定義に印刷されるとは思わない、私はそれが空白だと思う。あなたの目には、現時点では$ http要求が解決されている間に一時的に未定義になったときに、すぐに正しい値を持つように見えます。