2016-10-21 28 views
1

新しいウェブデベロッパーはこちらです(事前に申し訳ありません)。 Angular2でプロトタイプの在庫ページを作成するように求められました。Angular2 APIで表示されない呼び出しを呼び出す

以下のコードで確認します。 EXAMPLEapi.serviceページから始めて、基本バックエンドAPI( 'https://api.EXAMPLE.com/api/v1/inventory?')を呼び出して、EXAMPLEapi.componentのngOnInitに渡して、初期在庫をページに読み込みます。

ここからは、さまざまなフィルタリング値(最小/最大年、Milage、色など)を選択できる必要があります。これらの値はフォーム(EXAMPLEapi.component.html)からrefreshInv()関数(EXAMPLEapi.component)に渡され、最終的にAPI呼び出しに戻される前にURLSearchParamsを使用して値をparamsに変換します。

APIは、ベースURLの最後に 'min_price ='を追加するだけで、それに応じて在庫呼び出しに反映されるように構築されています。

問題は次のとおりです。onSubmitが通過するフィルタリング値を通過すると、正常にステータス200のネットワークコールを正常に取得できます。残念ながら、在庫はページに戻っていません。それは空白です。

EXAMPLEAPI.service.ts

import {Injectable} from 'angular2/core'; 
import {Http} from 'angular2/http'; 
import {Observable} from 'rxjs/Observable'; 
import 'rxjs/add/operator/map'; 


@Injectable() 
export class EXAMPLEAPIService { 
constructor(public http: Http){} 

baseUrl = "https://api.EXAMPLE.com/api/v1/inventory?"; 


getVehicles(params) { 
    return this.http.get(this.baseUrl, params) 
     .map(res => res.json()); 
} 

click(): Observable<Data[]> { 
    console.log(value); 
} 

log(x) { 
    console.log(x); 
} 

EXAMPLE.component.ts

import {Component, OnInit} from 'angular2/core'; 
import {Http, RequestOptions, URLSearchParams, HTTP_PROVIDERS}  from 'angular2/http'; 
import {Observable} from 'rxjs/Observable'; 
import 'rxjs/add/operator/map'; 
import {EXAMPLEService} from './EXAMPLEapi.service'; 
import {FormsModule} from 'angular2/forms'; 


@Component({ 
selector: 'example-container', 
styles: [` 
     * { 
      display: inline-block; 
      max-width: 500px; 
      vertical-align: top; 
     } 
     .invbar { 
      border: 1px solid black; 
      padding: 5px; 
      background-color: #6A7372; 
      border-radius: 15px; 
     } 
     .hotel_container{ 
      border: 1px solid black; 
      background-color: #6A7372; 
      max-height: 410px; 
     } 
     #colorsBox{ 
      display: block; 
     } 
     input[type="checkbox"]{ 
      margin-left: 5px; 
     } 
     label{ 
      margin-top: 5px; 
      color: #FF3B37; 
     } 
    `], 
templateUrl: 'app/exampleapi.component.html', 
providers: [HTTP_PROVIDERS, EXAMPLEAPIService] 
}) 

export class EXAMPLEAPIComponent implements OnInit { 
constructor(public EXAMPLEAPIService: EXAMPLEAPIService){ 


    this.minPrice = { 
     value: '' 
    }; 
    this.maxPrice = { 
     value: '' 
    }; 
    this.minYear = { 
     value: '2013' 
    }; 
    this.maxYear = { 
     value: '' 
    }; 

} 

// On Page-Load this loads the API Call 
ngOnInit() { 
    this.EXAMPLEService.getVehicles() 
     .subscribe(data => { 
      this.vehicles = data.data; 
      console.log(data.data[0].name); 
     } 
} 

// Takes the Filter Parameters and passes them back into the API Call 
refreshInv() { 
    let params = new URLSearchParams(); 
    params.set('min_price', this.minPrice.value); 
    params.set('max_price', this.maxPrice.value); 
    params.set('min_year', this.minYear.value); 
    params.set('max_year', this.maxYear.value); 
    params.set('ext_color', this.colorsChecked); 

    let options = new RequestOptions({ 
     search: params 
    }); 
    console.log(options); 
    return this.EXAMPLEService.getVehicles(options) 
     .subscribe(data => this.vehicles = data.data); 
} 

// Keeps the Filter Queries Actively Refreshing on each interaction 
onSubmit(value: any): Observable<Data[]> { 
    console.log(value); 
    return this.refreshInv() 
}; 

// Dynamic Checkbox Generation for Color Filters 
colors = ['Red', 'Blue', 'Yellow', 'Green', 'White', 'Black']; 
colorsMap = { 
    Red: false, 
    Blue: false, 
    Yellow: false, 
}; 
colorsChecked = []; 

initColorsMap() { 
    for (var x=0; x<this.colors.length; x++) { 
     this.colorsMap[this.colors[x]] = true; 
    } 
} 

updateCheckedColors(color, event) { 
    this.colorsMap[color] = event.target.checked; 
} 

colorUpdate() { 
    for(var x in this.colorsMap) { 
     if(this.colorsMap[x]) { 
      this.colorsChecked.push[x]; 
     } 
    } 
    this.colors = this.colorsChecked; 
    this.colorsChecked = []; 
} 

// Dynamic Checkbox Generation for Lift Filters 
lifts = ['Lifted', 'Unlifted']; 
liftsMap = { 
    Lifted: false, 
    Unlifted: false, 
}; 
liftsChecked = []; 

initLiftsMap() { 
    for (var x=0; x<this.lifts.length; x++) { 
     this.liftsMap[this.maps[x]] = true; 
    } 
} 

updateCheckedMaps(map, event) { 
    this.liftsMap[lift] = event.target.checked; 
} 

liftUpdate() { 
    for(var x in this.liftMap) { 
     if(this.liftMap[x]) { 
      this.liftsChecked.push[x]; 
     } 
    } 
    this.lifts = this.liftsChecked; 
    this.liftsChecked = []; 
} 

// Dynamic Checkbox Generation for Transmission Filters 
trans = ['Manual', 'Automatic']; 
transMap = { 
    Manual: false, 
    Automatic: false, 
}; 
transChecked = []; 

initTransMap() { 
    for (var x=0; x<this.trans.length; x++) { 
     this.transMap[this.trans[x]] = true; 
    } 
} 

updateCheckedmap(map, event) { 
    this.transMap[map] = event.target.checked; 
} 

transUpdate() { 
    for(var x in this.transMap) { 
     if(this.transMap[x]) { 
      this.transChecked.push[x]; 
     } 
    } 
    this.trans = this.transChecked; 
    this.transChecked = []; 
} 

// Dynamic Checkbox Generation for Interior Filters 
ints = ['Cloth', 'Leather', 'Vinyl']; 
intsMap = { 
    Cloth: false, 
    Leather: false, 
    Vinyl: false, 
}; 
intsChecked = []; 

initIntMap() { 
    for (var x=0; x<this.ints.length; x++) { 
     this.intsMap[this.ints[x]] = true; 
    } 
} 

updateCheckedmap(map, event) { 
    this.intsMap[map] = event.target.checked; 
} 

intsUpdate() { 
    for(var x in this.intsMap) { 
     if(this.intsMap[x]) { 
      this.intsChecked.push[x]; 
     } 
    } 
    this.ints = this.intsChecked; 
    this.intsChecked = []; 
} 


} 
+0

また、angular2を@angularに更新することもできます。 angle2は古いです。 https://angular.io/docs/ts/latest/guide/npm-packages.html – Knostradamus

答えて

0

まず最初にすべての、あなたがangular2 plnkrを(設定方法の一例をしたい場合pkgを使用して)、look here

コードでは、refreshInvは、サブスクリプションを返します(Observable.subscribe()はサブスクリプションを返します)。サブスクリプションは使用できませんが、サブスクライブしません。

私はうまく機能し、コードを単純化する別のアプローチを提案したいと思います。実際にあなたのデータフローは 'query' - > 'request' - > 'display'です。 rxjsでは、これは簡単にコード化されているよう:urlParamsMapperはJSONベースのクエリを取得します(あなたが指定したように)とURLSearchParamsに変換

let items$ = jsonParams$ 
    .map(urlParamsMapper) 
    .switchMap(urlParams => http.get(baseUrl, urlParams) 
    .map(response => response.json().data); 

jsonParams$を使用すると、関連するクエリの詳細を更新することができます(私たちの場合は件名で)観測可能である:

let jsonParams$: Subject<any> = new BehaviorSubject({ 
    min_price: '', 
    max_price: '', 
    ... 
    ext_color: '' 
}); 

、あなたのparamsを更新するたびに、あなたの新しいJSONを構築する(あなたは、ロジックを持っていますあなたのコード内で)、その後の操作を行います。あなたはonNext代わりのnext使用する必要がありますrxjs 4で

jsonParams$.next(currentParams); 

注意を。

これはチェーン全体を引き起こします。

<my-item-renderer *ngFor="let item; of items$ | async;" [item]="item"></my-item> 

注意あなたがオブザーバーにバインドすることができますasync:あなたのテンプレートにそれを結合する

最後のステップは次のようになります。サービスで

あなたはおそらくサービスでHTTP呼び出しを維持すなわち、あなたのサービスアーキテクチャを維持したいと思いますので、今、あなたはそうのようにそれを破るしたい場合があります

createItemsLoader(jsonParams$: Observable<any>): Observable<Array<any>> { 
    return jsonParams$.map(urlParamsMapper) 
    .switchMap(urlParams => http.get(baseUrl, urlParams)) 
    .map(response => response.json().data); 
} 

その後、あなたのコンポーネントで:

let jsonParams$: Subject<any> = new BehaviorSubject({min_price: '' ...}); 
let items$ = ItemsService.createItemsLoader(jsonParams$); 

refreshInv() { 
    .... let jsonParams: any = construct json params .... 
    this.jsonParams$.next(jsonParams); 
} 

そして、あなたが適切にあなたの配管を構築する場合、これは、反応性プログラミングの美しさ、あなたがしなければならないすべては右のパイプの下に新しいデータを送信することですもう片方を聞いている人はそれを得るでしょう。上記のコードは手続き的な「考え方」にあります。

+0

あなたの回答を確認した後、私たちはあなたの記事に非常によく似たアプローチをとることにしました。コードははるかにクリーンでより粘着的です。どうもありがとうございます! – NWMSDoug

+0

私は助けてくれると嬉しいです。リアクティブは異なる考え方であり、適応するには時間がかかります。古い習慣は激しく枯れ、古いプログラミングモデルのように振る舞うように強制しようとしている人たちがいる。数ヶ月前に私はこれを読む:https://gist.github.com/staltz/868e7e9bc2a7b8c1f754(数回)、私はそれが私に良い出発点を与えたと思う。 私は新しいプロジェクトを開始するときに、まずすべての入力、出力、およびそれらがどのように混合するかを書き留めました。私には簡単に実装できるグラフがあります。その点から、物事ははるかに単純であり、新しい行動を追加することは、それを正しい場所に差し込むことの問題です。 – Meir

関連する問題