कोणीय: जिसमें जीवनचक्र हुक इनपुट डेटा घटक के लिए उपलब्ध है


85

मेरे पास एक घटक है जो डेटा के imageरूप में वस्तुओं की एक सरणी प्राप्त करता है Input

export class ImageGalleryComponent {
  @Input() images: Image[];
  selectedImage: Image;
}

मैं चाहूंगा कि जब घटक लोड करता है तो selectedImageमान को imagesसरणी के पहले ऑब्जेक्ट पर सेट किया जाए । मैंने इसे इस OnInitतरह से जीवन चक्र हुक में करने की कोशिश की है :

export class ImageGalleryComponent implements OnInit {
  @Input() images: Image[];
  selectedImage: Image;
  ngOnInit() {
    this.selectedImage = this.images[0];
  }
}

इससे मुझे एक त्रुटि मिलती है Cannot read property '0' of undefinedजिसका अर्थ है कि imagesइस स्तर पर मूल्य निर्धारित नहीं है। मैंने भी OnChangesहुक की कोशिश की है, लेकिन मैं फंस गया हूं क्योंकि मुझे किसी सरणी के परिवर्तनों का निरीक्षण करने के तरीके के बारे में जानकारी नहीं मिल सकती है। मैं अपेक्षित परिणाम कैसे प्राप्त कर सकता हूं?

मूल घटक इस तरह दिखता है:

@Component({
  selector: 'profile-detail',
  templateUrl: '...',
  styleUrls: [...],
  directives: [ImageGalleryComponent]
})

export class ProfileDetailComponent implements OnInit {
  profile: Profile;
  errorMessage: string;
  images: Image[];
  constructor(private profileService: ProfileService, private   routeParams: RouteParams){}

  ngOnInit() {
    this.getProfile();
  }

  getProfile() {
    let profileId = this.routeParams.get('id');
    this.profileService.getProfile(profileId).subscribe(
    profile => {
     this.profile = profile;
     this.images = profile.images;
     for (var album of profile.albums) {
       this.images = this.images.concat(album.images);
     }
    }, error => this.errorMessage = <any>error
   );
 }
}

मूल घटक के टेम्पलेट में यह है

...
<image-gallery [images]="images"></image-gallery>
...

1
imagesमूल घटक में डेटा कैसे पॉप्युलेट किया जा रहा है? यानी, यह एक http अनुरोध (एस) के माध्यम से है? यदि ऐसा है, तो आप http ऑब्जेक्टिव के लिए ImageGalleryComponent सब्सक्रिप्शन () कर सकते हैं।
मार्क राजकोक

@MarkRajcok imagesडेटा का एक हिस्सा है जिसका उपयोग माता-पिता द्वारा इस तरह किया जाता है {profile: {firstName: "abc", lastName: "xyz", images: [ ... ]}}जिसका अर्थ है कि अगर मैं बच्चे की सदस्यता लेता हूं, तो मुझे अभी भी माता-पिता की सदस्यता
लेनी

अगर चाइल्ड कंपोनेंट बनाते समय पेरेंट कंपोनेंट में इमेजेज एंप्लाइज हो जाती है, तो इमेजेज प्रॉपर्टी को ngOnInit () कहा जाता है। आपको इस बारे में अधिक जानकारी प्रदान करने की आवश्यकता होगी कि किसी और को आपकी मदद करने के लिए (या समस्या को दर्शाने वाला न्यूनतम प्लंकर बनाने के लिए) किसी के लिए पैरेंट घटक में चित्र सरणी कैसे पॉपुलेटेड है।
मार्क राजकॉक

@MarkRajcok मैंने मूल घटक को जोड़ा है और इसमें चित्र कैसे पॉपुलेट किए जाते हैं।
ऑप्टिमस पेटे

2
तो हां, ऐसा लगता है कि आपके माता-पिता घटक अपनी छवियों की संपत्ति को आबाद करने के लिए http (चूंकि यह एक सेवा का उपयोग कर रहे हैं) का उपयोग कर रहे हैं। चूँकि यह एक अतुल्यकालिक ऑपरेशन है, चाइल्ड कम्पोनेंट की इनपुट प्रॉपर्टी को उसके ngOnInit () मेथड के कॉल करने के समय तक पॉपुलेट नहीं किया जाएगा। अपना कोड ngOnInit () से ngOnChanges () में ले जाएँ और यह काम करना चाहिए।
मार्क राजकोक

जवाबों:


88

इनपुट संपत्तियों को पहले आबाद किया जाता है ngOnInit()कॉल करने जाता है। हालाँकि, यह अभिभावक की संपत्ति को मानता है जो इनपुट घटक को खिलाती है, जब बच्चा घटक बनाया जाता है तो पहले से ही आबादी है।

आपके परिदृश्य में, यह मामला नहीं है - छवियों के डेटा को एक सेवा से अतुल्यकालिक रूप से आबाद किया जा रहा है (इसलिए http अनुरोध)। इसलिए, जब ngOnInit()कहा जाता है तो इनपुट प्रॉपर्टी आबाद नहीं होगी ।

आपकी समस्या को हल करने के लिए, जब डेटा सर्वर से वापस आ जाता है, तो मूल संपत्ति के लिए एक नया सरणी असाइन करें। ngOnChanges()बच्चे में लागू करें । ngOnChanges()कहा जाता है जब कोणीय परिवर्तन का पता लगाने के लिए नए सरणी मूल्य को बच्चे के नीचे प्रचारित किया जाएगा।


1
मैं आपसे सहमत हूं क्योंकि मैंने खुद इसी समस्या का सामना किया था। ngOnchanges()बच्चे में लागू करने के बाद भी , त्रुटि Cannot read property '0' of undefinedआती है। लेकिन, ऐप बिना किसी समस्या के चल सकता है। यह त्रुटि इसलिए आती है क्योंकि प्रारंभ में, इनपुट संपत्ति आबाद नहीं हुई है। ngOnChanges()जब यह async कॉल से डेटा प्राप्त होता है तब यह दूसरी बार कॉल द्वारा पॉपुलेट किया जाता है। मेरे मामले के लिए, इस समाधान के अतिरिक्त, मैंने HTML में null ऑपरेटर के खिलाफ गार्ड जोड़ा । यह स्पष्ट रूप से त्रुटि को हल करता है।
थिलिना संहिता

7

आप अपनी छवियों के लिए एक सेटर भी जोड़ सकते हैं जिसे जब भी मूल्य में बदलाव कहा जाएगा और आप अपनी डिफ़ॉल्ट चयनित छवि को सेटर में ही सेट कर सकते हैं:

export class ImageGalleryComponent {
  private _images: Image[];

  @Input()
  set images(value: Image[]) {
      if (value) { //null check
          this._images = value;
          this.selectedImage = value[0]; //setting default selected image
      }
  }
  get images(): Image[] {
      return this._images;
  }

  selectedImage: Image;
}

1

आप बस कुछ चीजों को बदलकर इसे हल कर सकते हैं।

  export class ImageGalleryComponent implements OnInit {

  @Input() images: Image[];
  selectedImage: Image;

  ngOnChanges() {
      if(this.images) {
        this.selectedImage = this.images[0];
      }
  }

 }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.