पैरेंट क्लास से चाइल्ड कंपोनेंट मेथड - कोणीय कहें


130

मैंने एक चाइल्ड कंपोनेंट बनाया है जिसमें एक विधि है जिसे मैं आह्वान करना चाहता हूं।

जब मैं इस विधि को लागू करता हूं तो यह केवल console.log()लाइन को फायर करता है , यह testसंपत्ति सेट नहीं करेगा ??

नीचे मेरे परिवर्तनों के साथ त्वरित प्रारंभ कोणीय ऐप है।

माता-पिता

import { Component } from '@angular/core';
import { NotifyComponent }  from './notify.component';

@Component({
    selector: 'my-app',
    template:
    `
    <button (click)="submit()">Call Child Component Method</button>
    `
})
export class AppComponent {
    private notify: NotifyComponent;

    constructor() { 
      this.notify = new NotifyComponent();
    }

    submit(): void {
        // execute child component method
        notify.callMethod();
    }
}

बच्चा

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

@Component({
    selector: 'notify',
    template: '<h3>Notify {{test}}</h3>'
})
export class NotifyComponent implements OnInit {
   test:string; 
   constructor() { }

    ngOnInit() { }

    callMethod(): void {
        console.log('successfully executed.');
        this.test = 'Me';
    }
}

मैं testसंपत्ति को कैसे सेट कर सकता हूं ?



आप इस उत्तर को यहां देख सकते हैं: stackoverflow.com/a/53057589/6663458
मुहम्मद मबोरुक

जवाबों:


210

आप @ViewChildअधिक जानकारी के लिए इस लिंक की जाँच करके इसका उपयोग कर सकते हैं

प्रकार चयनकर्ता के साथ

बाल घटक

@Component({
  selector: 'child-cmp',
  template: '<p>child</p>'
})
class ChildCmp {
  doSomething() {}
}

मूल घटक

@Component({
  selector: 'some-cmp',
  template: '<child-cmp></child-cmp>',
  directives: [ChildCmp]
})
class SomeCmp {

  @ViewChild(ChildCmp) child:ChildCmp;

  ngAfterViewInit() {
    // child is set
    this.child.doSomething();
  }
}

स्ट्रिंग चयनकर्ता के साथ

बाल घटक

@Component({
  selector: 'child-cmp',
  template: '<p>child</p>'
})
class ChildCmp {
  doSomething() {}
}

मूल घटक

@Component({
  selector: 'some-cmp',
  template: '<child-cmp #child></child-cmp>',
  directives: [ChildCmp]
})
class SomeCmp {

  @ViewChild('child') child:ChildCmp;

  ngAfterViewInit() {
    // child is set
    this.child.doSomething();
  }
}

6
मैंने आपके दृष्टिकोण का अनुसरण किया, लेकिन मुझे निर्देश का उपयोग करते समय त्रुटि हो रही है: [चाइल्डकैम्प], त्रुटि कहती है: निर्देश 'प्रकार' घटक में मौजूद नहीं है। मैं इसे googled और पाया निर्देश rc5 में पदावनत है। तो नए संस्करण पर इसे कैसे संभालना है। कृपया मदद कीजिए।
वलीद शाहज़ेब

1
इस लिंक को आज़माएं angular.io/guide/component-interaction और निर्देशों की टिप्पणी करें
rashfmnb

5
जब एक ही कक्षा के एक से अधिक बच्चे हों तो यह कैसे करें?
आनंदु अजयकुमार

@rashfmnb "घोषणा की उम्मीद"। एक त्रुटि आ रही है जब मैं @ViewChild ('बच्चा') बच्चे को लिखने की कोशिश करता हूं: चाइल्डकैम्प, घटक में। कृपया सहायता कीजिए! और इसके अलावा, मैं इसे उसी निर्देश में आयात नहीं कर सकता, जो मुझे "निर्देश: (typeof EmployeeProfileC ... ') की तरह त्रुटि देता है, जो' प्रकार 'घटक के पैरामीटर के लिए लागू नहीं है। ऑब्जेक्ट शाब्दिक केवल ज्ञात गुणों को निर्दिष्ट कर सकता है, और' निर्देश 'नहीं करता है। टाइप 'कंपोनेंट' में मौजूद है। "
त्रिलोक पाठक

1
यह एक सही उत्तर है, लेकिन यह कसकर युग्मित घटकों का उत्पादन करता है । Inputगुणों का उपयोग करने के लिए एक बेहतर पैटर्न है : एक अवलोकन जो बच्चे को अपने स्वयं के आंतरिक फ़ंक्शन को कॉल करके प्रतिक्रिया करता है । User6779899 का उत्तर देखें
बोगदान डी

56

यह मेरे लिए काम किया! कोणीय 2 के लिए, मूल घटक में बाल घटक विधि को कॉल करें

Parent.component.ts

    import { Component, OnInit, ViewChild } from '@angular/core';
    import { ChildComponent } from '../child/child'; 
    @Component({ 
               selector: 'parent-app', 
               template: `<child-cmp></child-cmp>` 
              }) 
    export class parentComponent implements OnInit{ 
        @ViewChild(ChildComponent ) child: ChildComponent ; 

        ngOnInit() { 
           this.child.ChildTestCmp(); } 
}

Child.component.ts

import { Component } from '@angular/core';
@Component({ 
  selector: 'child-cmp', 
  template: `<h2> Show Child Component</h2><br/><p> {{test }}</p> ` 
})
export class ChildComponent {
  test: string;
  ChildTestCmp() 
  { 
    this.test = "I am child component!"; 
  }
 }


4
इस पंक्ति में चाइल्ड वीएम क्या है: @ व्यूचाइल्ड (चाइल्डकंपोनेंट) बच्चा: चाइल्ड वीएम;
वलीद

@AleedShahzaib मुझे लगता है कि ओपी का मतलब ChildComponentहैChildVM
अजीत शाह

1
मैंने सोचा था कि यह घटक का एक अलग उदाहरण बनाएगा लेकिन यह वास्तव में आपके उदाहरण से फ़ंक्शन को उस घटक की वर्तमान स्थिति में चर कहता है, पवित्र गाय! यह विधि पहले उत्तर की तुलना में बेहतर है!
tatsu

3
मुझे हमेशा "this.child" का अपरिभाषित मूल्य मिल रहा है
खन्ना

2
'This.child' के अपरिभाषित होने का मेरा अनुमान है कि ViewChild किसी ऐसी चीज़ की ओर संकेत कर रहा है जो टेम्पलेट में मौजूद नहीं है, या आप इसे जीवनचक्र में बहुत पहले एक्सेस करने की कोशिश कर रहे हैं, जैसे कि कंस्ट्रक्टर में।
टोनी

34

मुझे लगता है कि सबसे आसान तरीका विषय का उपयोग कर रहा है। साथी उदाहरण कोड में बच्चे को हर बार सूचित किया जाता है कि 'टेलचाइल्ड' कहा जाता है।

Parent.component.ts

import {Subject} from 'rxjs/Subject';
...
export class ParentComp {
    changingValue: Subject<boolean> = new Subject();
    tellChild(){
    this.changingValue.next(true);
  }
}

Parent.component.html

<my-comp [changing]="changingValue"></my-comp>

Child.component.ts

...
export class ChildComp implements OnInit{
@Input() changing: Subject<boolean>;
ngOnInit(){
  this.changing.subscribe(v => { 
     console.log('value is changing', v);
  });
}

Stackblitz पर काम कर रहा नमूना


4
यह एक सुरुचिपूर्ण समाधान है, हालांकि यह सभी मामलों में ठीक से काम नहीं करता है, शायद कारण से कोणीय परिवर्तन का पता नहीं चल रहा है।
अलेक्सी

1
यह मेरे उपयोग के मामले के लिए सबसे अच्छा समाधान हो पाया। एक जादू की तरह काम करता है। धन्यवाद!
वेस्टन

नीट! सरल मामलों के लिए, आप उस ऑब्जेक्ट को पारित करके विषय / सदस्यता ओवरहेड से बच सकते हैं जिसमें बच्चे को कॉलबैक विधि होती है। उपरोक्त के समान, माता-पिता से संकेत प्राप्त करने के लिए बच्चा कॉलबैक से आगे निकल जाता है।
SHR

@ क्या आपको कॉलबैक के साथ किसी ऑब्जेक्ट को पास करने का कोई मौका मिल सकता है?
इमाद एल हित्ती

1
यह एक सुंदर समाधान है, यह स्वीकृत उत्तर होना चाहिए, बस 'rxjs' से आयात विधि जैसे विषय को बदलें;
विकस कोहली

5

कोणीय - पैरेंट घटक के टेम्पलेट में चाइल्ड कंपोनेंट की विधि को बुलाओ

आपके पास ParentComponent और ChildComponent है जो इस तरह दिखता है।

parent.component.html

यहाँ छवि विवरण दर्ज करें

parent.component.ts

import {Component} from '@angular/core';

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css']
})
export class ParentComponent {
  constructor() {
  }
}

child.component.html

<p>
  This is child
</p>

child.component.ts

import {Component} from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent {
  constructor() {
  }

  doSomething() {
    console.log('do something');
  }
}

जब सेवा, यह इस तरह दिखता है:

यहाँ छवि विवरण दर्ज करें

जब उपयोगकर्ता पेरेंटकम्पोनेंट के इनपुट एलिमेंट पर ध्यान केंद्रित करता है, तो आप चाइल्डकम्पोनेंट के डोसोमेटिंग () विधि को कॉल करना चाहते हैं।

बस यह करें:

  1. App.com-चाइल्ड चयनकर्ता को parent.component.html में एक DOM वैरिएबल नाम (# - हैशटैग के साथ उपसर्ग) दें , इस मामले में हम इसे appChild कहते हैं।
  2. इनपुट तत्व के फ़ोकस इवेंट में अभिव्यक्ति मूल्य (जिस विधि को आप कॉल करना चाहते हैं) असाइन करें।

यहाँ छवि विवरण दर्ज करें

परिणाम:

यहाँ छवि विवरण दर्ज करें


ठीक है, लेकिन हम इसे ts
canbax

घटक के भीतर से उपयोग के लिए: @ViewChild('appChild', { static: false }) appChild: ElementRef<HTMLElement>;और बाद में उपयोग करेंthis.appChild.doSomething()
गिल एप्सर्टेन

4

user6779899 का उत्तर साफ और अधिक सामान्य है। हालांकि, इमाद एल हित्ती के अनुरोध के आधार पर, एक हल्के वजन समाधान का प्रस्ताव यहां दिया गया है। इसका उपयोग तब किया जा सकता है जब बच्चा घटक केवल एक माता-पिता से कसकर जुड़ा हो।

Parent.component.ts

export class Notifier {
    valueChanged: (data: number) => void = (d: number) => { };
}

export class Parent {
    notifyObj = new Notifier();
    tellChild(newValue: number) {
        this.notifyObj.valueChanged(newValue); // inform child
    }
}

Parent.component.html

<my-child-comp [notify]="notifyObj"></my-child-comp>

Child.component.ts

export class ChildComp implements OnInit{
    @Input() notify = new Notifier(); // create object to satisfy typescript
    ngOnInit(){
      this.notify.valueChanged = (d: number) => {
            console.log(`Parent has notified changes to ${d}`);
            // do something with the new value 
        };
    }
 }

2

निम्नलिखित उदाहरण पर विचार करें,

    import import { AfterViewInit, ViewChild } from '@angular/core';
    import { Component } from '@angular/core';
    import { CountdownTimerComponent }  from './countdown-timer.component';
    @Component({
        selector: 'app-countdown-parent-vc',
        templateUrl: 'app-countdown-parent-vc.html',
        styleUrl: [app-countdown-parent-vc.css]
    export class CreateCategoryComponent implements OnInit {
         @ViewChild(CountdownTimerComponent, {static: false})
         private timerComponent: CountdownTimerComponent;
         ngAfterViewInit() {
             this.timerComponent.startTimer();
         }

         submitNewCategory(){
            this.ngAfterViewInit();     
         }

@ViewChild के बारे में अधिक यहाँ पढ़ें ।


0

मेरे पास एक सटीक स्थिति थी जहां मूल-घटक का एक Selectरूप में एक तत्व था और सबमिट करने पर, मुझे चयनित तत्व से चयनित मूल्य के अनुसार प्रासंगिक बाल-घटक की विधि को कॉल करने की आवश्यकता थी।

Parent.HTML:

<form (ngSubmit)='selX' [formGroup]="xSelForm">
    <select formControlName="xSelector">
      ...
    </select>
<button type="submit">Submit</button>
</form>
<child [selectedX]="selectedX"></child>

Parent.TS:

selX(){
  this.selectedX = this.xSelForm.value['xSelector'];
}

Child.TS:

export class ChildComponent implements OnChanges {
  @Input() public selectedX;

  //ngOnChanges will execute if there is a change in the value of selectedX which has been passed to child as an @Input.

  ngOnChanges(changes: { [propKey: string]: SimpleChange }) {
    this.childFunction();
  }
  childFunction(){ }
}

उम्मीद है की यह मदद करेगा।

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