読者です 読者をやめる 読者になる 読者になる

Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

Angular4入門_Vol.10

参考サイト

https://www.codingforentrepreneurs.com/projects/try-angular-v4/

Http Requests

  • videoListの中身を、assets/json/videos.jsonファイルに移す。json形式に修正する。
[
  {
    "name": "Item 1",
    "slug": "item-1",
    "embed": "kzjMI00A1f8"
  },
  {
    "name": "Item 2",
    "slug": "item-2",
    "embed": "kzjMI00A1f8"
  },
  {
    "name": "Item 3",
    "slug": "item-3",
    "embed": null
  }
]
  • video-list.component.ts に追記する。
import { Component, OnInit, OnDestroy } from '@angular/core'; // OnDestroyをimportする
import { Http } from '@angular/http'; // Http moduleをimportする

@Component({
  selector: 'video-list',
  templateUrl: './video-list.component.html',
  styleUrls: ['./video-list.component.css']
})
export class VideoListComponent implements OnInit {
  private req:any; // req アノテーションをanyで定義する
  title = "Video List!";
  someItem = "<h1>HiHi</h1>";
  todayDate;
  // videoList = ["Item 1", "Item 2", "Item 3"];
  videoList = [
    {
      name: "Item 1",
      slug: "item-1",
      embed: `kzjMI00A1f8`
    },
    {
      name: "Item 2",
      slug: "item-2",
      embed: `kzjMI00A1f8`
    },
    {
      name: "Item 3",
      slug: "item-3",
      embed: ""
    },
  ]
  constructor(private http:Http) { } //http の型定義をHttpでセットする。

  ngOnInit() {
    this.todayDate = new Date();
    this.req = this.http.get('assets/json/videos.json').subscribe(data=>{
      console.log(data.json())
    }); //httpのgetmethodで、jsonファイルからデータを持ってくる。成功したら、data(jsonファイルの中身)をconsole.log(data.json())という形で、console.logに代入する。
  }

  ngOnDestroy(){
    this.req.unsubscribe()
  } // ngOnDestroyお設定しておく。(インスタンスが破棄されたときに、reqのsubscribeを中止する。)

  getEmbedUrl(item){
    return 'https://www.youtube.com/embed/' + item.embed;
  }

}
  • videoListの読み込みをjsonからに変更する。
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Http } from '@angular/http';

@Component({
  selector: 'video-list',
  templateUrl: './video-list.component.html',
  styleUrls: ['./video-list.component.css']
})
export class VideoListComponent implements OnInit {
  private req:any;
  title = "Video List!";
  someItem = "<h1>HiHi</h1>";
  todayDate;
  videoList: [any]; // videoList: [any] ; でclass定義する。

  constructor(private http:Http) { }

  ngOnInit() {
    this.todayDate = new Date();
    this.req = this.http.get('assets/json/videos.json').subscribe(data=>{
      console.log(data.json())
      this.videoList = data.json() as [any]; // videoListに、data.json()をリストany型として代入する。
    });
  }

  ngOnDestroy(){
    this.req.unsubscribe()
  }

  getEmbedUrl(item){
    return 'https://www.youtube.com/embed/' + item.embed;
  }

}
  • video-detail.component.ts にもjsonデータを使ってみる。
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Http } from '@angular/http'; //Httpをimport

@Component({
  selector: 'video-detail',
  templateUrl: './video-detail.component.html',
  styleUrls: ['./video-detail.component.css']
})
export class VideoDetailComponent implements OnInit, OnDestroy {
  private routeSub:any;
  private req:any;
  slug: string;
  constructor(private route: ActivatedRoute, private http: Http) { } // httpのclassを定義

  ngOnInit() {
    this.routeSub = this.route.params.subscribe(params => {
      console.log(params)
      this.slug = params['slug']
      this.http.get('assets/json/videos.json').subscribe(data=>{
        data.json().filter(item=>{
          console.log(item) // jsonデータを取得>subscribe>success>data.json()にitemでfilterをかけて、itemを表示する。itemは、
        })
      })
    })
  }
  ngOnDestroy(){
    this.routeSub.unsubscribe()
    this.req.unsubscribe()
  }

}
  • video変数を定義して、itemオブジェクトをvideo変数に代入する。
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Http } from '@angular/http';

@Component({
  selector: 'video-detail',
  templateUrl: './video-detail.component.html',
  styleUrls: ['./video-detail.component.css']
})
export class VideoDetailComponent implements OnInit, OnDestroy {
  private routeSub:any;
  private req:any;
  video:any; //videoを設定する。
  slug: string;
  constructor(private route: ActivatedRoute, private http: Http) { }

  ngOnInit() {
    this.routeSub = this.route.params.subscribe(params => {
      console.log(params)
      this.slug = params['slug']
      this.http.get('assets/json/videos.json').subscribe(data=>{
        data.json().filter(item=>{
          // console.log(item)
          if (item.slug == this.slug){
            this.video = item //itemオブジェクトをvideoに代入する。
          }
        })
      })
    })
  }
  ngOnDestroy(){
    this.routeSub.unsubscribe()
    this.req.unsubscribe()
  }

}
  • video変数をvideo-detail.component.html に反映する。
<h1>{{ video.name }}</h1>
  <p>
    {{ video.slug }}
  </p>
  • error!以下のようにngifを入れるとerrorが解消される、、、なぜだ。
<div *ngIf='video'>
<h1>{{ video.name }}</h1>
  <p>
    {{ video.slug }}
  </p>
</div>
  • どうも、videoのdefault valueが設定されていないと、htmlを読み込んだ時点で、videoオブジェクトが無いと判断されて、video.nameが呼び出すことができないということ?とりあえず、video-detail.component.tsのvideoのvalueを設定する。
video = {
  name: "Default",
  slug: "item-1",
  embed: "kzjMI00A1f8"
};
  • そして、htmlも、ngIfを外してみる。
<h1>{{ video.name }}</h1>
  <p>
    {{ video.slug }}
  </p>
  • 無事表示された。やはりdefaultが設定されていないことが原因らしい。

  • 最終的に、htmlファイルを以下のように修正した。

<!-- ngIfで、videoの有無を判断
>videoオブジェクトが無い場合は、Loading表示
>ある場合は、videoオブジェクトから、プロパティを取り出す。
video?の部分は、videoがあるかないかを確認してある場合に、nameプロパティを取り出す-->
<div *ngIf='!video'>Loading...</div>
<h1>{{ video?.name }}</h1>
  <p>
    {{ video?.slug }}
  </p>
  • video-detail.component.tsも以下のようにdefaultを設定していない状態に戻す。(これでも今回はうまく表示されるはず)
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Http } from '@angular/http';

@Component({
  selector: 'video-detail',
  templateUrl: './video-detail.component.html',
  styleUrls: ['./video-detail.component.css']
})
export class VideoDetailComponent implements OnInit, OnDestroy {
  private routeSub:any;
  private req:any;
  // video = {
  //   name: "Default",
  //   slug: "item-1",
  //   embed: "kzjMI00A1f8"
  // };
  video:any;
  slug: string;
  constructor(private route: ActivatedRoute, private http: Http) { }

  ngOnInit() {
    this.routeSub = this.route.params.subscribe(params => {
      console.log(params)
      this.slug = params['slug']
      this.http.get('assets/json/videos.json').subscribe(data=>{
        data.json().filter(item=>{
          // console.log(item)
          if (item.slug == this.slug){
            this.video = item
          }
        })
      })
    })
  }
  ngOnDestroy(){
    this.routeSub.unsubscribe()
    this.req.unsubscribe()
  }

}

まとめ

  • httpインスタンスのgetメソッドなどは使いやすそうやな。たぶん、フォームとかだとpostを使うんやろな。
  • default valueが設定されているか、ngIfなどで、オブジェクトの有無を判断しないとうまく表示されない場合があるというのは、覚えておこう。