2017-09-05 23 views
9

से गतिशील रूप से एमडी-कार्ड बनाएं I मैं एक एपीआई कॉल कर रहा हूं और उपयोगकर्ता प्रोफाइल का एक समूह संग्रहीत कर रहा हूं, और मैं प्रत्येक प्रोफ़ाइल के लिए गतिशील रूप से कार्ड (कोणीय सामग्री डिजाइन एमडी कार्ड) बनाने में सक्षम होना चाहता हूं। लौटाई गई प्रोफ़ाइल की संख्या भिन्न हो सकती है, इसलिए इसे गतिशील होना चाहिए।एपीआई प्रतिक्रिया

यह जो JSONP अनुरोध करता है और profiles चर में संग्रहीत करता है प्रोफाइल मेरी घटक फ़ाइल है:

import {Component, Injectable, OnInit} from '@angular/core'; 
import {Jsonp} from '@angular/http'; 

@Component({ 
    selector: 'app-staff', 
    templateUrl: './staff.component.html', 
    styleUrls: ['./staff.component.css'] 
}) 
@Injectable() 
export class StaffComponent implements OnInit { 
    public searchField: string; 
    apiRoot = 'this/is/my/api/url'; 
    public results: JSON; 
    public profiles; 

    constructor(private jsonp: Jsonp) { 
    } 

    ngOnInit() { 
    } 

    setSearchField(field: string){ // ignore this method 
    this.searchField = field; 
    console.log('Received field: ' + this.searchField); 
    } 

    search(term: string) { 
    const apiUrl = `${this.apiRoot}?search=${term}&rows=10&callback=JSONP_CALLBACK`; 
    return this.jsonp.request(apiUrl).map(results => { this.results = results.json(); console.log(this.results['profiles'][0]); this.profiles = results['profiles']; return results.json(); }); 
    } 

} 

यह ऊपर घटक है, जहां मैं *ngFor उपयोग करने के लिए एक बनाने के लिए कोशिश कर रहा हूँ के लिए टेम्पलेट है md-card की सूची:

<div class="container-fluid"> 
    <div class="row justify-content-center"> 
    <div class="col-md-auto"> 
     <ul> 
     <li *ngFor="let profile of profiles"> 
      <md-card class="example-card"> 
      <md-card-header> 
       <div md-card-avatar class="example-header-image"></div> 
       <md-card-title>{{profile.fullName}}</md-card-title> 
       <md-card-subtitle>Department</md-card-subtitle> 
      </md-card-header> 
      <img md-card-image src="../assets/image.png"> 
      <md-card-content> 
       <p> 
       This section of the card will contain information about the result being searched for. It could also be 
       accompanied by additional information such as links. 
       </p> 
      </md-card-content> 
      <md-card-actions> 
       <button md-button>APPLY</button> 
       <button md-button>GO TO xyz</button> 
      </md-card-actions> 
      </md-card> 
     </li> 
     </ul> 
    </div> 
    </div> 
</div> 

मेरे प्रोफाइल डेटा एक सरणी के रूप में है (मान लेते हैं कि सरणी 10 की लंबाई से अधिक नहीं है) और निम्नलिखित रूप लेता है:

0: {fullName: "Foo Bar", emailAddress: "[email protected]", image: "/profile/image/foobar/foobar.jpg", phoneNumber: "99999999"}, 

1: {fullName: "Foo Bar1", emailAddress: "[email protected]", image: "/profile/image/foobar1/foobar1.jpg", phoneNumber: "919999999"} 

हालांकि, md-card को प्रस्तुत नहीं किया जा रहा है। मैंने जांच की है कि profiles खाली नहीं है। मैं प्रोफ़ाइल की संख्या के आधार पर गतिशील रूप से कार्ड कैसे बना सकता हूं और प्रोफ़ाइल ऑब्जेक्ट्स से मूल्यों के साथ सामग्री को पॉप्युलेट कर सकता हूं?

+0

आपके 'प्रोफाइल' डेटा कैसा दिखता है?कैब आप इसे अपने प्रश्न में जोड़ते हैं? – Faisal

+0

@ फैसल मैंने अपने प्रश्न में 'प्रोफ़ाइल' डेटा के बारे में अधिक जानकारी दी है। – bawse

+0

'this.profiles = परिणाम ['प्रोफाइल']' होना चाहिए .profiles = this.results ['profiles'] 'या 'this.profiles = results.json() [' प्रोफाइल ']' – cyrix

उत्तर

5

आप rxjs से BehaviorSubject का उपयोग करने का प्रयास कर सकते हैं और प्रतिक्रिया से प्रोफाइल को उत्सर्जित कर सकते हैं। अपने टेम्पलेट में async पाइप का उपयोग करें। इससे यह सुनिश्चित होगा कि कोणीय के परिवर्तन का पता लगाने से बदलाव आएंगे।

private readonly profiles$$ = new BehaviorSubject([]); 
public readonly profiles$ = this.profiles$$.asObservable(); 

// ... 

search(term: string) { 
    const apiUrl = `${this.apiRoot}?search=${term}&rows=10&callback=JSONP_CALLBACK`; 
    return this.jsonp.request(apiUrl).map(res => { 
    let results = res.json(); 
    this.profiles$$.next(results.profiles); 
    return results; 
    }); 
} 

और अपने खाके में:

<li *ngFor="let profile of profiles$ | async"> 
    <!-- ... --> 
</li> 

Btw: घटक से @Injectable डेकोरेटर निकालें, घटकों injectable नहीं होना चाहिए।

नोट: आपको वास्तव में एपीआई कॉल को साझा सेवा में ले जाने पर विचार करना चाहिए, यह आपके घटक के तर्क को साफ रखेगा और आप इसे अन्य घटकों में भी उपयोग कर सकते हैं। इसके अलावा आप redux "पैटर्न" के बारे में स्वयं को सूचित कर सकते हैं, इसके लिए आप @ngrx/store और @ngrx/effects देख सकते हैं। अधिक जानकारी @ngrx/platform monorepo पर मिल सकती है। यह आपको आपके एप्लिकेशन के राज्य के बारे में बड़ा नियंत्रण देगा और बाहरी डेटा से आपके डेटा और नियंत्रण अनुरोध/प्रतिक्रियाओं को प्रबंधित करना आसान है।

+0

आपके उत्तर के लिए धन्यवाद, मैंने आपके दृष्टिकोण की कोशिश की है लेकिन मुझे कंसोल में एक त्रुटि मिल रही है। 'NgForOr' से बंधे नहीं जा सकते क्योंकि यह 'li' की ज्ञात संपत्ति नहीं है। कृपया सलाह दें कि यहां से कैसे आगे बढ़ना है। मैंने घटक से इंजेक्शन योग्य सजावटी को भी हटा दिया है, यह एक गलती थी। – bawse

+0

मुझे लगता है कि आपका मतलब '' ngForOf 'है क्योंकि यह' li'' की ज्ञात संपत्ति नहीं है, क्या आपने घटक के साथ अपने मॉड्यूल में '@ कोणीय/सामान्य' से 'सामान्य मॉड्यूल' आयात किया था? – cyrix

+0

नहीं, कंसोल त्रुटि स्पष्ट रूप से 'ngForOr' कहती है। मैंने 'कॉमन मॉड्यूल' आयात किया है। क्या आप एक प्लंकर प्रदान करने में सक्षम हैं? मैंने शुरुआत में अपनी कोणीय सेवा स्थापित करने के लिए इस ट्यूटोरियल का पालन किया, इसलिए यहां उपयोग की गई एपीआई का उपयोग करने में संकोच न करें: https://codecraft.tv/courses/angular/http/jsonp-with-observables/ – bawse

0

आपका परिणाम मानचित्र() में संसाधित किया गया है और अभी भी Observable|promise लौटाता है, इसलिए आपको सर्वर से आने वाले मान के async व्यवहार को संभालने की आवश्यकता है।

कोणीय async पाइप प्रदान करते हैं, आप अपने टेम्पलेट में यह कहने के लिए उपयोग कर सकते हैं कि जब भी डेटा मेरे यूआई में दिखाई देगा।

आप एक @Injectable() सेवा है जो प्रत्यक्ष वापसी और स्टोर अपने घटक चर में है कि और फिर अपने यूआई आप कर सकते हैं सरल उपयोग async पाइप

<ul> 
    <li *ngFor="let profile of profiles | async"> 
     <md-card class="example-card"> 
     <md-card-header> 

यह प्रत्यक्ष और साथ पूरी तरह से काम करता है http में होगा करने के लिए अपने सर्वर कॉल स्थानांतरित कर सकते हैं कोणीय एपीआई में कॉल करता है। जब आपका कोणीय भार होता है, तो यह टेम्पलेट बाध्यकारी को समाप्त करता है लेकिन सर्वर से डेटा उसके बाद आता है, यही कारण है कि आपका डेटा यूआई में प्रतिबिंबित नहीं होता है। तो आपको उस async व्यवहार को संभालना होगा। उम्मीद है कि यह मदद करता है :)

+0

यह काम नहीं करेगा , क्योंकि वह 'मानचित्र' कॉल के अंदर 'प्रोफाइल' सेट कर रहा है । इसलिए 'प्रोफाइल' एक अवलोकन योग्य नहीं है। – cyrix

+1

ओह वह प्रोफाइल का उपयोग कर रहा है! मैंने सोचा कि वह परिणाम का उपयोग कर रहा है। मैं परिणाम के लिए अपना उत्तर बदलूंगा ताकि यह –

+1

काम करेगा, अफसोस की बात है कि वह अपने घटक के अंदर एपीआई कॉल कर रहा है और परिणाम को 'मैप' के अंदर लागू कर रहा है जो परिवर्तन को लेने के लिए कोणीय के परिवर्तन का पता लगाने का कारण बनता है। लेकिन आपका जवाब सही होगा अगर 'प्रोफाइल' मेरे अपमान के रूप में एक अवलोकन योग्य होगा। – cyrix

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