2

Angular1 から Angular2 にいくつかのコードを移行していますが、いくつかの問題があります。json 応答を開き、テンプレートに入力し、テンプレート ng 関数からデータにアクセスできますが、コンポーネント クラスから直接データにアクセスすることはできませんでした。私が読んだこととAngular2 http / observableが純粋なjsonオブジェクトを返していないように見えるエラーメッセージから、再マップする必要があると思われますが、その方法はわかりません。onPromise を使用して promise に戻すことも可能であると思いますが、それを機能させることができませんでした。私は解決策を探すのに多くの時間を費やし、それらのほとんどを実装しようとしましたが、うまくいきませんでした。応答を使用可能な形式に再マッピングする方法や、応答内のデータに直接アクセスする方法について誰かがアドバイスできる場合は、大歓迎です。

サービスからの http 呼び出しの例:-

getExam() {
    return this._http.get('/json/exam.json')
      .map(data => data.json());
  }

サブスクライブの例:-

  ngOnInit() {
      this._examsService.getExam()
        .subscribe(response => this.exam = response);
    console.log(this.exam.length);  //this fails
  }

コンソール ログ エラーの例:-

TypeError: Cannot read property 'length' of undefined in [null]

データ構造の例 (テスト用に非常に単純化) :-

{"title":"My Practice Exam",
  "questions":[
    {"question":"1+1 = ",
      "answers":[
        {"answer":"2","correct":"Y","selected":"N","iscorrect":""},
        {"answer":"5","correct":"N","selected":"N","iscorrect":""}]},
    {"question":"2+2 = ",
      "answers":[
        {"answer":"4","correct":"Y","selected":"N","iscorrect":""},
        {"answer":"7","correct":"N","selected":"N","iscorrect":""}]},
    {"question":"3+3 = ",
      "answers":[
        {"answer":"6","correct":"Y","selected":"N","iscorrect":""},
        {"answer":"8","correct":"N","selected":"N","iscorrect":""}]}]}

Angular1 では、関数からデータに直接アクセスできました。たとえば、次のように、Angular2 でも同様のことをしたいと考えています。

if ($scope.myExams[0].questions[q].answers[a].correct == 'y') ...
4

2 に答える 2

4

このコードで

ngOnInit() {
  this._examsService.getExam()
    .subscribe(response => this.exam = response);
  console.log(this.exam.length);  //this fails
}

最初の行はリクエストthis._examsService.getExam() .subscribe(...)を送信し、レスポンスへの関心を登録してから実行されますが、サーバーへの接続とレスポンスの受信がまだ完了していないためconsole.log(this.exam.length)、この時点でrespone => this.exam = responseはまだ実行されていません。getExam()

次のように、最終的に返されるデータを操作するには、一連のイベントにとどまる必要があります。

ngOnInit() {
  this._examsService.getExam()
    .subscribe(response => {
      this.exam = response;
      console.log(this.exam.length);  //this shoudn't fail anymore
    });
}

これで問題が解決するかどうかはわかりませんが、あなたの質問は、より精巧な解決策の要件に関する十分な情報を提供していません。

于 2016-01-21T14:11:35.737 に答える
1

以下のケースは正常な動作だと思います。

ngOnInit() {
  this._examsService.getExam()
    .subscribe(response => this.exam = response);
  console.log(this.exam.length);  //this fails
}

length後で設定されるオブジェクトのプロパティにアクセスしようとするためexam、応答が(subscribeメソッドで)そこにあるためです。

そうは言っても、オブザーバブル内でエラーがスローされた場合、mapオペレーターは呼び出されません。catchエラー応答を変換する場合は、以下で説明するように、演算子を利用できます。

this._examsService.getExam()
    .subscribe(
      // Success
      response => this.exam = response,
      // Failure
      response => {
        // Do something
      });

および対応するサービス コード:

getExam() {
  return this.http.get('http://...')
           .map(res = > res.json())
           .catch(res => {
             // If you want to extract the JSON error
             // message from the response
             return Observable.throw(res.json());
           });
}

それ以外の場合は、asyncパイプを利用してコンポーネントにオブザーバブルを直接設定し、サブスクライブを行わないこともできます。

this.exam = this._examsService.getExam();

および関連するテンプレートで

<ul>
  <li *ngFor="#e of exam | async">{{e.name}}</li>
</ul>

お役に立てば幸いです、ティエリー

于 2016-01-21T14:09:48.353 に答える