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

Djangoroidの奮闘記

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

Angular4入門_Vol.17

参考サイト

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

Search Video List

  • search methodを、videos.service.tsに追記する。methodの処理の方法は、get methodと似てるので、中身をコピペして再利用する。
search(query){
  return this.http.get(endpoint) // get methodで、endpointにアクセス
          .map(response=>{ // responseを代入して結果をmappingする
            let data = [] // data に空のリストを代入
            let req = response.json().filter(item=>{ // response.json()のデータをitemのname
                              if (item.name.indexOf(query) >= 0 ){ //indexOf
                                  data.push(item) // itemをpushする。
                              }
                            })
            return data
            })
          .catch(this.handleError)
}
  • indexOfは、indexOf() メソッドは、呼び出す String オブジェクト中で、fromIndex から検索を始め、指定された値が最初に現れたインデックスを返します。値が見つからない場合は -1 を返します。とのことなので、>=0としてある場合は、文字列を少なくとも1つは含む場合でfilterをかけていることになる。

  • 試しに、video-list.component.tsにsearch methodを記載してみる。

  ngOnInit() {
    this.todayDate = new Date();
    this.req = this._video.search("テスト1").subscribe(data=>{
      this.videoList = data as [any];
    }); //search("テスト1") で、引数として文字列を与えてみる。
  }
  • 無事テスト1だけ表示された!テストは成功したので、searchからlist()methodに戻しておく。

  • search-detailに、search methodを追記する。

import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { VideoService } from '../videos/videos.service'; //VideoServiceをimportする


@Component({
  selector: 'app-search-detail',
  templateUrl: './search-detail.component.html',
  styleUrls: ['./search-detail.component.css'],
  providers: [VideoService] //VideoServiceをprovidersとして、定義する
})
export class SearchDetailComponent implements OnInit, OnDestroy {
  private routeSub:any;
  private req:any;
  query: string;
  videoList: [any];

  constructor(private route: ActivatedRoute, private _video:VideoService) { } //_vidoe にVideoServiceを型定義する。

  ngOnInit() {
    this.routeSub = this.route.params.subscribe(params=>{
      console.log(params)
      this.query = params['q']
      this.req = this._video.search(this.query).subscribe(data=>{ //searchメソッドを、引数をqueryとして組み込む
        this.videoList = data as [any];
      })
    })
  }

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

}
  • search boxに、キーワードを入れて検索してみる。。。。何も表示されない。。。

  • video-list.component.html の、video listを表示する箇所のhtmlのコードをコピペしてみる。

<p *ngIf='query'>
  Searched for <b>{{ query }}</b>
</p>

<div *ngFor='let item of videoList'>
  <h1><a href="videos/{{ item.slug }}" >{{ item.name }}</a></h1>
  <!-- <div [innerHTML]='item.embed'></div>
  <div [innerHTML]='someItem'></div> -->
  <iframe *ngIf='item.embed' width="560" height="315" [src]="getEmbedUrl(item) | safe" frameborder="0" allowfullscreen></iframe>
  <hr>
</div>
  • Error発生! ERROR TypeError: co.getEmbedUrl is not a functionとのこと。なので、getEmbedUrlを定義する。
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { VideoService } from '../videos/videos.service';


@Component({
  selector: 'app-search-detail',
  templateUrl: './search-detail.component.html',
  styleUrls: ['./search-detail.component.css'],
  providers: [VideoService]
})
export class SearchDetailComponent implements OnInit, OnDestroy {
  private routeSub:any;
  private req:any;
  query: string;
  videoList: [any];

  constructor(private route: ActivatedRoute, private _video:VideoService) { }

  ngOnInit() {
    this.routeSub = this.route.params.subscribe(params=>{
      console.log(params)
      this.query = params['q']
      this.req = this._video.search(this.query).subscribe(data=>{
        this.videoList = data as [any];
      })
    })
  }

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

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

}
  • これで再度検索してみる。。。できた〜!

まとめ

  • serviceは、apiからデータを取得>加工>componentに渡す 役割があるぽい。
  • もしかしたら、componentからデータ加工の指示>serviceを通じてapiのデータを変更・削除などもserviceでやるのか?それはまた別なのかな。