2015-12-24 9 views
14

मैं कोणीय 2-बीटा के साथ खेलने की कोशिश कर रहा हूं और मैं एचटीपी घटक के साथ काम करना चाहता हूं।कोणीय 2 बीटा में एक सेवा में कुशलतापूर्वक एचटीपी घटक का उपभोग कैसे करें?

मैं कोणीय 2 में this और मैं जानता हूँ कि पढ़ (विपरीत कोणीय 1), Http घटक है एक सेवा है जो एक वादा रिटर्न नहीं: लेकिन यहाँ एक गंभीर समस्या है। यह पर्यवेक्षक नामक कुछ देता है। हम जानते हैं कि एक घटक बेहतर है एचटीपी का उपयोग न करें। एचटीपी उपभोग करने के लिए जिम्मेदार सेवा बनाने का कुशल तरीका है। पर कैसे?! अनुरोध पूरा करने के बाद, क्या एक वादा वापस कर देना चाहिए? (here देखें)

क्या यह बिल्कुल समझ में आता है ?!

+1

आप ** '.toromrom()' को जोड़कर एक वचन के रूप में HTTP का उपयोग कर सकते हैं, इसके बाद '.then()' कॉल की आपकी श्रृंखला के बाद। फिर भी, अवलोकन योग्य अनुशंसित दृष्टिकोण हैं। –

+1

@EvanPlaice हाँ मैंने उनके बारे में पढ़ा है और अब मैं पर्यवेक्षकों का प्रशंसक हूं :) –

+0

इस पर एक नज़र डालें http://stackoverflow.com/a/34758630/5043867 –

उत्तर

23

सेवाओं को लागू करने के लिए कोणीय 2 के साथ संभव है। वे नीचे वर्णित इंजेक्शन योग्य वर्गों के अनुरूप हैं। इस मामले में इस वर्ग को घटकों जैसे अन्य तत्वों में इंजेक्शन दिया जा सकता है।

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

@Injectable() 
export class CompanyService { 
    constructor(http:Http) { 
    this.http = http; 
    } 
} 

आप एक Http वस्तु उस में हालत आप HTTP_PROVIDERS निर्दिष्ट जब आपके आवेदन के मुख्य घटक bootstraping पर (अपने निर्माता का प्रयोग करके) इंजेक्षन कर सकते हैं:

import {bootstrap} from 'angular2/platform/browser' 
import {HTTP_PROVIDERS} from 'angular2/http'; 
import {AppComponent} from './app.component' 

bootstrap(AppComponent, [ 
    HTTP_PROVIDERS 
]); 

यह सेवा फिर एक में इंजेक्ट किया जा सकता है घटक, जैसा कि नीचे वर्णित है। घटक की providers सूची में इसे निर्दिष्ट करना न भूलें।

import { Component, View, Inject } from 'angular2/core'; 
import { CompanyService } from './company-service'; 

@Component({ 
    selector: 'company-list', 
    providers: [ CompanyService ], 
    template: ` 
    (...) ` 
}) 

export class CompanyList { 
    constructor(private service: CompanyService) { 
    this.service = service; 
    } 
} 

फिर आप एक विधि आपकी सेवा में Http वस्तु लाभ को लागू करने और प्रत्यक्ष वस्तु आपके अनुरोध करने के लिए इसी लौट सकते हैं:

@Injectable() 
export class CompanyService { 
    constructor(http:Http) { 
    this.http = http; 
    } 

    getCompanies() { 
    return this.http.get('https://angular2.apispark.net/v1/companies/') 
        .map(res => res.json()); 
    } 
} 

घटक तो यह getCompanies विधि कॉल और पर एक कॉलबैक सदस्यता ले सकते हैं जब घटक घटक की स्थिति को अद्यतन करने के लिए प्रतिक्रिया होती है तो अवलोकन करने योग्य वस्तु को सूचित किया जाता है (उसी तरह आपने कोणीय 1 में वादे के साथ किया था):

export class CompanyList implements OnInit { 
    public companies: Company[]; 

    constructor(private service: CompanyService) { 
    this.service = service; 
    } 

    ngOnInit() { 
    this.service.getCompanies().subscribe(
     data => this.companies = data); 
    } 
} 

संपादित

foxx के रूप में उसकी टिप्पणी में सुझाव दिया, async पाइप भी परोक्ष नमूदार वस्तु पर सदस्यता के लिए इस्तेमाल किया जा सकता। इसका उपयोग करने का तरीका यहां दिया गया है।सबसे पहले विशेषता में नमूदार वस्तु डाल करने के लिए अपने घटक को अद्यतन आप प्रदर्शित करना चाहते:

export class CompanyList implements OnInit { 
    public companies: Company[]; 

    constructor(private service: CompanyService) { 
    this.service = service; 
    } 

    ngOnInit() { 
    this.companies = this.service.getCompanies(); 
    } 
} 

उपयोग तो अपने खाके में async पाइप:

@Component({ 
    selector: 'company-list', 
    providers: [ CompanyService ], 
    template: ` 
    <ul> 
     <li *ngFor="#company of companies | async">{{company.name}}</li> 
    </ul> 
    ` 
}) 
export class CompanyList implements OnInit { 
    (...) 
} 

दो भागों में इस लेख के रूप में अधिक जानकारी दे सकता है अच्छी तरह से:

आशा है कि यह आप, थियरी

+7

आप मैन्युअल रूप से सदस्यता लेने के बजाय एसिंक पाइप का उपयोग करना चाहेंगे । – foxx

+0

आपकी टिप्पणी के लिए बहुत बहुत धन्यवाद @foox! मैंने एसिंक पाइप का उपयोग करने का वर्णन करने के लिए अपना उत्तर अपडेट किया ;-) –

+0

एक छोटा सवाल, आपने बूटस्ट्रैप में 'HTTP_PROVIDERS' आयात किया लेकिन 'ROUTER_PROVIDERS' इंजेक्शन दिया। क्या यह एक टाइपो है? –

6

एक वादा में नमूदार Http के प्राप्त द्वारा दिया() विधि कन्वर्ट करने के लिए कोई जरूरत नहीं है मदद करता है। ज्यादातर मामलों में, सेवा केवल देखने योग्य वापस कर सकते हैं।

हम एक सरणी या सर्वर से एक आदिम प्रकार (यानी, स्ट्रिंग, संख्या, बुलियन) फ़ेच कर रहे हैं, तो हम अपने टेम्पलेट में सीधे लौटे नमूदार का उपयोग कर, asyncPipe साथ द्वारा हमारे नियंत्रक तर्क सरल बना सकते हैं । यह पाइप स्वचालित रूप से अवलोकन करने योग्य (यह एक वादे के साथ भी काम करता है) की सदस्यता लेगा और यह सबसे हालिया मूल्य वापस कर देगा जो अवलोकन योग्य है। जब कोई नया मान उत्सर्जित होता है, तो पाइप घटक को परिवर्तनों के लिए चेक करने के लिए चिह्नित करता है, इसलिए दृश्य स्वचालित रूप से नए मान के साथ अपडेट हो जाएगा।

हम सर्वर से एक वस्तु फ़ेच कर रहे हैं, तो मैं इस प्रकार किसी भी तरह से asyncPipe, उपयोग करने के लिए हम सुरक्षित नेविगेशन ऑपरेटर के साथ async पाइप इस्तेमाल कर सकते हैं संयोजन के रूप में, के बारे में पता नहीं कर रहा हूँ:

{{(objectData$ | async)?.name}} 

लेकिन यह जटिल लग रहा है, और हमें उस ऑब्जेक्ट प्रॉपर्टी के लिए दोहराना होगा जिसे हम प्रदर्शित करना चाहते हैं।

इसके बजाय, मैं घटक में देखने योग्य में subscribe() का सुझाव देता हूं और निहित वस्तु को घटक गुण में संग्रहीत करता हूं। हम तब safe navigation operator (?।) या (जैसा कि टिप्पणी में उल्लिखित @Evan Plaice के रूप में) टेम्पलेट में NgIf का उपयोग करें। अगर हम सुरक्षित नेविगेशन ऑपरेटर या NgIf का उपयोग नहीं करते हैं, तो टेम्पलेट पहले प्रस्तुत करने का प्रयास करते समय एक त्रुटि फेंक दी जाएगी, क्योंकि ऑब्जेक्ट अभी तक किसी मान के साथ पॉप्युलेट नहीं किया गया है।

ध्यान दें कि नीचे दी गई सेवा हमेशा प्राप्त विधियों के लिए एक अवलोकन योग्य कैसे होती है।

service.ts

import {Injectable} from 'angular2/core'; 
import {Http} from 'angular2/http'; 
import 'rxjs/add/operator/map'; // we need to import this now 

@Injectable() 
export class MyService { 
    constructor(private _http:Http) {} 
    getArrayDataObservable() { 
    return this._http.get('./data/array.json') 
     .map(data => data.json()); 
    } 
    getPrimitiveDataObservable() { 
    return this._http.get('./data/primitive.txt') 
     .map(data => data.text()); // note .text() here 
    } 
    getObjectDataObservable() { 
    return this._http.get('./data/object.json') 
     .map(data => data.json()); 
    } 
} 

app.ts

import {Component} from 'angular2/core'; 
import {MyService} from './my-service.service'; 
import {HTTP_PROVIDERS} from 'angular2/http'; 

@Component({ 
    selector: 'my-app', 
    providers: [HTTP_PROVIDERS, MyService], 
    template: ` 
    <div>array data using '| async': 
     <div *ngFor="#item of arrayData$ | async">{{item}}</div> 
    </div> 
    <div>primitive data using '| async': {{primitiveData$ | async}}</div> 
    <div>object data using ?.: {{objectData?.name}}</div> 
    <div *ngIf="objectData">object data using NgIf: {{objectData.name}}</div>` 
}) 
export class AppComponent { 
    constructor(private _myService:MyService) { console.clear(); } 
    ngOnInit() { 
    this.arrayData$  = this._myService.getArrayDataObservable(); 
    this.primitiveData$ = this._myService.getPrimitiveDataObservable(); 
    this._myService.getObjectDataObservable() 
     .subscribe(data => this.objectData = data); 
    } 
} 

नोट: मैं सेवा विधि के नाम में "प्रत्यक्ष" डाल – जैसे, getArrayDataObervable() – सिर्फ उजागर करने के लिए इस विधि का एक प्रत्यक्ष रिटर्न । आम तौर पर आप नाम में "अवलोकन" नहीं डालेंगे।

डेटा/array.json

[ 1,2,3 ] 

डेटा/आदिम।json

Greetings SO friends! 

डेटा/object.json

{ "name": "Mark" } 

आउटपुट:

array data using '| async': 
1 
2 
3 
primitive data using '| async': Greetings SO friends! 
object data using .?: Mark 
object data using NgIf: Mark 

Plunker


एक usin साथ खामी जी async पाइप यह है कि घटक में सर्वर त्रुटियों को संभालने के लिए कोई तंत्र नहीं है। मैं answered another question बताता हूं कि घटक में ऐसी त्रुटियों को कैसे पकड़ें, लेकिन हमें इस मामले में हमेशा subscribe() का उपयोग करने की आवश्यकता है।

+1

'?' (एल्विस) ऑपरेटर के लिए एक उपयोगी विकल्प टेम्पलेट अनुभाग में '* ngIf' सशर्त जोड़ने के लिए है जहां डेटा का उपयोग किया जाएगा। यह एक कोरसर ग्रेनेड कंट्रोल प्रदान करता है, इसलिए आपको टेम्प्लेट पर एल्विस ऑपरेटरों को छिड़कने की चिंता करने की ज़रूरत नहीं है या इस बारे में चिंता करने की ज़रूरत नहीं है कि जब कोई डेटा नहीं दिया जाता है तो टेम्पलेट कैसा दिखाई देगा। –

+0

@EvanPlaice, धन्यवाद, मैंने आपके सुझाव को शामिल करने के लिए उत्तर अपडेट किया। –

संबंधित मुद्दे