कोणीय 2 @ दृश्यमान एनोटेशन अपरिभाषित करता है


242

मैं कोणीय 2 सीखने की कोशिश कर रहा हूं।

मैं @ViewChild एनोटेशन का उपयोग करके एक मूल घटक से एक बच्चे के घटक तक पहुंचना चाहूंगा

यहाँ कोड की कुछ पंक्तियाँ हैं:

में BodyContent.ts मेरे पास है:

import {ViewChild, Component, Injectable} from 'angular2/core';
import {FilterTiles} from '../Components/FilterTiles/FilterTiles';


@Component({
selector: 'ico-body-content'
, templateUrl: 'App/Pages/Filters/BodyContent/BodyContent.html'
, directives: [FilterTiles] 
})


export class BodyContent {
    @ViewChild(FilterTiles) ft:FilterTiles;

    public onClickSidebar(clickedElement: string) {
        console.log(this.ft);
        var startingFilter = {
            title: 'cognomi',
            values: [
                'griffin'
                , 'simpson'
            ]}
        this.ft.tiles.push(startingFilter);
    } 
}

जबकि FilterTiles.ts में :

 import {Component} from 'angular2/core';


 @Component({
     selector: 'ico-filter-tiles'
    ,templateUrl: 'App/Pages/Filters/Components/FilterTiles/FilterTiles.html'
 })


 export class FilterTiles {
     public tiles = [];

     public constructor(){};
 }

अंत में यहाँ टेम्प्लेट (जैसा कि टिप्पणियों में सुझाया गया है):

BodyContent.html

<div (click)="onClickSidebar()" class="row" style="height:200px; background-color:red;">
        <ico-filter-tiles></ico-filter-tiles>
    </div>

FilterTiles.html

<h1>Tiles loaded</h1>
<div *ngFor="#tile of tiles" class="col-md-4">
     ... stuff ...
</div>

FilterTiles.html टेम्प्लेट को सही ढंग से ico- filter- टाइल्स टैग में लोड किया गया है (वास्तव में मैं हेडर देखने में सक्षम हूं)।

नोट: BodyContent वर्ग को एक अन्य टेम्पलेट (Body) के अंदर इंजेक्ट किया जा रहा है जो कि DynamicsComponetLoader का उपयोग कर रहा है: dcl.loadAsRoot (BodyContent, '# ico-bodyContent', इंजेक्टर):

import {ViewChild, Component, DynamicComponentLoader, Injector} from 'angular2/core';
import {Body}                 from '../../Layout/Dashboard/Body/Body';
import {BodyContent}          from './BodyContent/BodyContent';

@Component({
    selector: 'filters'
    , templateUrl: 'App/Pages/Filters/Filters.html'
    , directives: [Body, Sidebar, Navbar]
})


export class Filters {

    constructor(dcl: DynamicComponentLoader, injector: Injector) {
       dcl.loadAsRoot(BodyContent, '#ico-bodyContent', injector);
       dcl.loadAsRoot(SidebarContent, '#ico-sidebarContent', injector);

   } 
}

समस्या यह है कि जब मैं ftकंसोल लॉग में लिखने की कोशिश करता हूं, मुझे मिलता है undefined, और निश्चित रूप से मुझे एक अपवाद मिलता है जब मैं "टाइल" सरणी के अंदर कुछ धक्का देने की कोशिश करता हूं: '' अपरिभाषित '' के लिए कोई संपत्ति टाइल नहीं

एक और बात: FilterTiles घटक सही ढंग से भरा हुआ लगता है, क्योंकि मैं इसके लिए html टेम्पलेट देख पा रहा हूं।

कोई उपाय? धन्यवाद


सही लग रहा है। हो सकता है कि टेम्पलेट के साथ कुछ हो, लेकिन यह आपके प्रश्न में शामिल नहीं है।
गुंटर ज़ोचबॉयर 12

1
गुंटर से सहमत। मैंने आपके कोड और सरल संबद्ध टेम्प्लेट के साथ एक प्लंकर बनाया और यह काम करता है। : यह लिंक देखें plnkr.co/edit/KpHp5Dlmppzo1LXcutPV?p=preview । हमें टेम्प्लेटों की आवश्यकता है ;-)
थियरी टेम्पलियर

1
ftकंस्ट्रक्टर में सेट नहीं किया जाएगा, लेकिन एक क्लिक ईवेंट हैंडलर में इसे पहले ही सेट कर दिया जाएगा।
गुंटर ज़ोचबॉयर

5
आप उपयोग कर रहे हैं loadAsRoot, जिसमें परिवर्तन का पता लगाने के साथ एक ज्ञात समस्या है । बस यह सुनिश्चित कर लें उपयोग करने का प्रयास करने के लिए loadNextToLocationया loadIntoLocation
एरिक मार्टिनेज

1
समस्या थी loadAsRoot। एक बार जब मैंने loadIntoLocationसमस्या को हल कर लिया था। यदि आप अपनी टिप्पणी को उत्तर के रूप में बनाते हैं तो मैं इसे स्वीकार कर सकता हूं
एंड्रिया इलेंटी

जवाबों:


374

मेरे पास एक समान मुद्दा था और मुझे लगा कि अगर कोई और गलती करता है तो मैं पोस्ट करूंगा। सबसे पहले, एक बात पर विचार करना है AfterViewInit; इससे पहले कि आप अपनी पहुँच प्राप्त कर सकें, आपको दृश्य के आरंभ होने की प्रतीक्षा करने की आवश्यकता है @ViewChild। हालाँकि, मैं @ViewChildअभी भी अशक्त लौट रहा था। समस्या मेरी थी *ngIf*ngIfनिर्देश मेरे नियंत्रण घटक की हत्या की गई थी तो मैं इसे संदर्भ नहीं कर सका।

import {Component, ViewChild, OnInit, AfterViewInit} from 'angular2/core';
import {ControlsComponent} from './controls/controls.component';
import {SlideshowComponent} from './slideshow/slideshow.component';

@Component({
    selector: 'app',
    template:  `
        <controls *ngIf="controlsOn"></controls>
        <slideshow (mousemove)="onMouseMove()"></slideshow>
    `,
    directives: [SlideshowComponent, ControlsComponent]
})

export class AppComponent {
    @ViewChild(ControlsComponent) controls:ControlsComponent;

    controlsOn:boolean = false;

    ngOnInit() {
        console.log('on init', this.controls);
        // this returns undefined
    }

    ngAfterViewInit() {
        console.log('on after view init', this.controls);
        // this returns null
    }

    onMouseMove(event) {
         this.controls.show();
         // throws an error because controls is null
    }
}

उम्मीद है की वो मदद करदे।

EDIT
जैसा कि नीचे @Ashg द्वारा उल्लेख किया गया है , एक समाधान @ViewChildrenइसके बजाय उपयोग करना है @ViewChild


9
@kenecaswell तो क्या आपने समस्या को हल करने का बेहतर तरीका ढूंढ लिया। मैं भी इसी मुद्दे का सामना कर रहा हूं। मेरे पास कई * एनजीआई हैं ताकि तत्व सभी सही होने के बाद ही हो, लेकिन मुझे तत्व संदर्भ की आवश्यकता है। इसे हल करने का कोई तरीका>
मोनिका

4
मैंने पाया कि चाइल्ड कंपोनेंट ngAfterViewInit () में 'अपरिभाषित' है अगर एनजीआईएफ का उपयोग कर रहे हैं। मैंने लंबे टाइमआउट लगाने की कोशिश की लेकिन फिर भी कोई असर नहीं हुआ। हालाँकि, बाद में चाइल्ड कंपोनेंट उपलब्ध है (यानी ईवेंट आदि क्लिक करने के लिए)। अगर मैं ngIf का उपयोग नहीं करता हूं और इसे ngAfterViewInit () में अपेक्षा के अनुसार परिभाषित किया गया है। माता-पिता / बाल संचार पर यहाँ अधिक है angular.io/docs/ts/latest/cookbook/…
मैथ्यू

3
मैंने बूटस्ट्रैप ngClass+ hiddenक्लास का इस्तेमाल किया ngIf। वह काम किया। धन्यवाद!
रहमतुल्ला एम।

9
यह समस्या को हल नहीं करता है, नीचे दिए गए समाधान का उपयोग करें @ व्यू चिल्ड्रेन गो को उपलब्ध होने के बाद बच्चे के नियंत्रण का एक संदर्भ मिलता है
एशग

20
यह सिर्फ "मुद्दा" साबित होता है, है ना? यह एक समाधान पोस्ट नहीं करता है।
मिगुएल रिबेरो

146

जैसा कि पहले बताया गया है कि यह मुद्दा ngIfअपरिभाषित है। उत्तर के ViewChildrenबजाय उपयोग करना है ViewChild। मेरे पास ऐसा ही मुद्दा था जहां मैं नहीं चाहता था कि एक ग्रिड तब तक दिखाया जाए जब तक कि सभी संदर्भ डेटा लोड न हो गए हों।

एचटीएमएल:

   <section class="well" *ngIf="LookupData != null">
       <h4 class="ra-well-title">Results</h4>
       <kendo-grid #searchGrid> </kendo-grid>
   </section>

घटक कोड

import { Component, ViewChildren, OnInit, AfterViewInit, QueryList  } from '@angular/core';
import { GridComponent } from '@progress/kendo-angular-grid';

export class SearchComponent implements OnInit, AfterViewInit
{
    //other code emitted for clarity

    @ViewChildren("searchGrid")
    public Grids: QueryList<GridComponent>

    private SearchGrid: GridComponent

    public ngAfterViewInit(): void
    {

        this.Grids.changes.subscribe((comps: QueryList <GridComponent>) =>
        {
            this.SearchGrid = comps.first;
        });


    }
}

यहां हम उपयोग कर रहे हैं ViewChildrenजिस पर आप परिवर्तनों के लिए सुन सकते हैं। इस मामले में संदर्भ के साथ किसी भी बच्चे #searchGrid। उम्मीद है की यह मदद करेगा।


4
मैं आपको कुछ मामलों में जोड़ना चाहूंगा जब आप बदलाव की कोशिश करेंगे। this.SearchGridगुण जो आपको वाक्यविन्यास का उपयोग करना चाहिए जैसे setTimeout(()=>{ ///your code here }, 1); अपवाद से बचने के लिए: अभिव्यक्ति की जाँच के बाद बदल गया है
रफालसा

3
यदि आप अपने #searchGrid टैग को सामान्य HTML तत्व पर Angular2 तत्व के बजाय रखना चाहते हैं तो आप यह कैसे करते हैं? (उदाहरण के लिए, <div #searchGrid> </ div> और यह एक * ngIf ब्लॉक के अंदर है;
Vern Jensen

1
यह मेरे उपयोग के मामले के लिए सही उत्तर है! धन्यवाद मुझे एक घटक का उपयोग करने की आवश्यकता है क्योंकि यह ngIf =
जमे

1
यह अजाक्स प्रतिक्रियाओं पर सही काम करता है, अब *ngIfकाम करता है, और रेंडर करने के बाद हम एक तत्व को डायनामिक घटकों से बचा सकते हैं।
एलपोर्फिरियो

4
यह भी एक सदस्यता के लिए इसे आवंटित करने के लिए मत भूलना और फिर से सदस्यता समाप्त
tam.teixeira

64

आप के लिए एक सेटर का उपयोग कर सकते हैं @ViewChild()

@ViewChild(FilterTiles) set ft(tiles: FilterTiles) {
    console.log(tiles);
};

यदि आपके पास एक एनजीआईएफ आवरण है, तो सेटर को अपरिभाषित कहा जाएगा, और फिर एक बार एक संदर्भ के साथ एनजीआईएफ इसे प्रस्तुत करने की अनुमति देता है।

मेरा मुद्दा हालांकि कुछ और था। मैंने अपने app.modules में अपने "FilterTiles" वाले मॉड्यूल को शामिल नहीं किया था। टेम्पलेट में कोई त्रुटि नहीं थी, लेकिन संदर्भ हमेशा अपरिभाषित था।


3
यह मेरे लिए काम नहीं कर रहा है - मुझे पहला अपरिभाषित मिलता है, लेकिन मुझे दूसरी कॉल w / संदर्भ नहीं मिलती है। App एक ng2 है ... क्या यह ng4 + सुविधा है?
जे कमिंस

@ मुझे विश्वास है कि यह इसलिए है क्योंकि आपने इस मामले में, कोणीय के साथ घटक पंजीकृत नहीं किया है FilterTiles। मैंने उस कारण से पहले उस मुद्दे का सामना किया है।
पार्लियामेंट

1
HTML तत्व पर #paginator और एनोटेशन जैसे # 8 का उपयोग करके कोणीय 8 के लिए काम करता है@ViewChild('paginator', {static: false})
Qiteq

1
क्या यह ViewChild परिवर्तनों के लिए एक कॉलबैक है?
यासर नस्सिमेंटो

24

इसने मेरे लिए काम किया।

उदाहरण के लिए, 'माय-कंपोनेंट' नाम के मेरे घटक को * ngIf = "showMe" का उपयोग करके प्रदर्शित किया गया था:

<my-component [showMe]="showMe" *ngIf="showMe"></my-component>

इसलिए, जब घटक को इनिशियलाइज़ किया जाता है तब तक घटक को तब तक प्रदर्शित नहीं किया जाता है जब तक कि "showMe" सत्य न हो। इस प्रकार, मेरे @ दृश्यदर्शी संदर्भ सभी अपरिभाषित थे।

यह वह जगह है जहां मैंने @ViewChildren और QueryList का उपयोग किया है जो इसे लौटाता है। देखें QueryList पर कोणीय लेख और एक @ViewChildren उपयोग डेमो

आप QueryList का उपयोग कर सकते हैं जो @ViewChildren रिटर्न करता है और नीचे दिए गए अनुसार rxjs का उपयोग करके संदर्भित आइटम में किसी भी परिवर्तन की सदस्यता लेता है। @ViewChild में यह क्षमता नहीं है।

import { Component, ViewChildren, ElementRef, OnChanges, QueryList, Input } from '@angular/core';
import 'rxjs/Rx';

@Component({
    selector: 'my-component',
    templateUrl: './my-component.component.html',
    styleUrls: ['./my-component.component.css']
})
export class MyComponent implements OnChanges {

  @ViewChildren('ref') ref: QueryList<any>; // this reference is just pointing to a template reference variable in the component html file (i.e. <div #ref></div> )
  @Input() showMe; // this is passed into my component from the parent as a    

  ngOnChanges () { // ngOnChanges is a component LifeCycle Hook that should run the following code when there is a change to the components view (like when the child elements appear in the DOM for example)
    if(showMe) // this if statement checks to see if the component has appeared becuase ngOnChanges may fire for other reasons
      this.ref.changes.subscribe( // subscribe to any changes to the ref which should change from undefined to an actual value once showMe is switched to true (which triggers *ngIf to show the component)
        (result) => {
          // console.log(result.first['_results'][0].nativeElement);                                         
          console.log(result.first.nativeElement);                                          

          // Do Stuff with referenced element here...   
        } 
      ); // end subscribe
    } // end if
  } // end onChanges 
} // end Class

आशा है कि यह किसी को कुछ समय और हताशा को बचाने में मदद करता है।


3
वास्तव में आप समाधान अब तक सूचीबद्ध सबसे अच्छा तरीका है। नोट हमें यह ध्यान रखना है कि शीर्ष 73 समाधान अब समाप्त हो गया है ... निर्देश के बाद से: [...] घोषणा को अब कोणीय 4 में समर्थित नहीं किया गया है। मैं इसे कोणीय 4 परिदृश्य में काम नहीं
करूंगा

5
सदस्यता समाप्त करने या उपयोग करने के लिए मत भूलना .take(1).subscribe(), लेकिन उत्कृष्ट जवाब, बहुत बहुत धन्यवाद!
ब्लेयर कोनोली

2
उत्कृष्ट समाधान। मैंने ngAfterViewInit () के बजाय ngOnChanges () में रेफरी परिवर्तन की सदस्यता ली है। लेकिन मुझे अभिव्यक्ति से छुटकारा पाने के लिए एक
सेटटाइमआउट

इसे वास्तविक समाधान के रूप में चिह्नित किया जाना चाहिए। आपका बहुत बहुत धन्यवाद!
प्लेटज़ेरश

10

[style.display]="getControlsOnStyleDisplay()"इसके बजाय मेरे वर्कअराउंड का उपयोग करना था *ngIf="controlsOn"। ब्लॉक है, लेकिन यह प्रदर्शित नहीं होता है।

@Component({
selector: 'app',
template:  `
    <controls [style.display]="getControlsOnStyleDisplay()"></controls>
...

export class AppComponent {
  @ViewChild(ControlsComponent) controls:ControlsComponent;

  controlsOn:boolean = false;

  getControlsOnStyleDisplay() {
    if(this.controlsOn) {
      return "block";
    } else {
      return "none";
    }
  }
....

एक पृष्ठ है जहाँ वस्तुओं की एक सूची एक तालिका में दर्शाई गई है, या शो-ऑफ चर के मूल्य के आधार पर संपादित आइटम को दिखाया गया है। [Style.display] = "! Showlist" का उपयोग करके कष्टप्रद कंसोल त्रुटि से छुटकारा पा लिया, * ngIf = "! ShowList" के साथ संयुक्त।
रज़वानोन

9

यह सुनिश्चित करने के लिए कि मेरी समस्या का हल क्या है, के लिए staticनिर्धारित किया गया था false

@ViewChild(ClrForm, {static: false}) clrForm;

साथ staticबंद कर दिया, @ViewChildसंदर्भ कोणीय से अपडेट होने पर *ngIfनिर्देश बदल जाता है।


1
यह लगभग सही उत्तर देने वाला है, बस इंगित करने के लिए अशक्त मूल्यों की जांच करने के लिए एक अच्छा विकल्प है, इसलिए हम कुछ इस तरह से समाप्त करते हैं: @ViewChild (ClrForm, {स्थैतिक: असत्य}) सेट clrForm (clrForm: ClrForm) {यदि (clrForm) {this.clrForm = clrForm; }};
क्लॉस क्लेन

मैंने बहुत सी चीजों की कोशिश की और आखिरकार इस चीज को दोषी पाया।
मनीष शर्मा

8

मेरा समाधान इसके *ngIf साथ प्रतिस्थापित करना था [hidden]। डाउनसाइड बच्चे के सभी घटक कोड डोम में मौजूद थे। लेकिन मेरी आवश्यकताओं के लिए काम किया।


5

मेरे मामले में, मेरे पास एक इनपुट वैरिएबल सेटर था ViewChild, और यह ViewChildएक *ngIfनिर्देश के अंदर था , इसलिए सेटर इसे प्रस्तुत करने से पहले इसे एक्सेस करने की कोशिश कर रहा था *ngIf(यह बिना ठीक काम करेगा *ngIf, लेकिन यह हमेशा सेट होने पर काम नहीं करेगा। सच के साथ *ngIf="true")।

हल करने के लिए, मैंने Rxjs का उपयोग यह सुनिश्चित करने के लिए किया कि ViewChildजब तक दृश्य आरंभ न हो जाए, तब तक प्रतीक्षा करें। सबसे पहले, एक विषय बनाएँ, जो देखने के बाद जब पूरा हो जाए।

export class MyComponent implements AfterViewInit {
  private _viewInitWaiter$ = new Subject();

  ngAfterViewInit(): void {
    this._viewInitWaiter$.complete();
  }
}

फिर, एक ऐसा फंक्शन बनाएं जो विषय के पूरा होने के बाद एक लैम्ब्डा को लेता और निष्पादित करता है।

private _executeAfterViewInit(func: () => any): any {
  this._viewInitWaiter$.subscribe(null, null, () => {
    return func();
  })
}

अंत में, ViewChild इस फ़ंक्शन का उपयोग करने के लिए सुनिश्चित करें।

@Input()
set myInput(val: any) {
    this._executeAfterViewInit(() => {
        const viewChildProperty = this.viewChild.someProperty;
        ...
    });
}

@ViewChild('viewChildRefName', {read: MyViewChildComponent}) viewChild: MyViewChildComponent;

1
यह सभी सेटलमेंट बकवास
Liam

4

यह काम करना होगा।

लेकिन जैसा कि गुंटर ज़ोचबॉयर ने कहा कि टेम्पलेट में कुछ अन्य समस्या होनी चाहिए। मैंने थोड़े प्रासंगिक-प्लंकर-उत्तर बनाए हैं । प्लीज ब्राउजर के कंसोल को चेक करें।

boot.ts

@Component({
selector: 'my-app'
, template: `<div> <h1> BodyContent </h1></div>

      <filter></filter>

      <button (click)="onClickSidebar()">Click Me</button>
  `
, directives: [FilterTiles] 
})


export class BodyContent {
    @ViewChild(FilterTiles) ft:FilterTiles;

    public onClickSidebar() {
        console.log(this.ft);

        this.ft.tiles.push("entered");
    } 
}

filterTiles.ts

@Component({
     selector: 'filter',
    template: '<div> <h4>Filter tiles </h4></div>'
 })


 export class FilterTiles {
     public tiles = [];

     public constructor(){};
 }

यह एक सम्मोहन की तरह काम करता है। कृपया अपने टैग और संदर्भों की दोबारा जांच करें।

धन्यवाद...


1
यदि समस्या मेरी जैसी ही है, तो डुप्लिकेट करने के लिए आपको <फिल्टर> </ फ़िल्टर> के आसपास टेम्पलेट में एक * एनजीआईएफ लगाने की आवश्यकता होगी .. जाहिर है अगर एनजीआईएफ झूठे लौटता है, तो व्यूहिल वायर्ड नहीं होता है और शून्य रिटर्न करता है
दान

2

यह मेरे लिए काम करता है, नीचे उदाहरण देखें।

import {Component, ViewChild, ElementRef} from 'angular2/core';

@Component({
    selector: 'app',
    template:  `
        <a (click)="toggle($event)">Toggle</a>
        <div *ngIf="visible">
          <input #control name="value" [(ngModel)]="value" type="text" />
        </div>
    `,
})

export class AppComponent {

    private elementRef: ElementRef;
    @ViewChild('control') set controlElRef(elementRef: ElementRef) {
      this.elementRef = elementRef;
    }

    visible:boolean;

    toggle($event: Event) {
      this.visible = !this.visible;
      if(this.visible) {
        setTimeout(() => { this.elementRef.nativeElement.focus(); });
      }
    }

}


2

मेरे पास एक समान मुद्दा था, जहां ViewChild एक switchखंड के अंदर था जो कि संदर्भित होने से पहले दृश्य तत्व को लोड नहीं कर रहा था। मैंने इसे एक अर्ध-हैकरी तरीके से हल किया, लेकिन ViewChildसंदर्भ को setTimeoutतुरंत निष्पादित किया गया (यानी 0ms)


1

इसका मेरा समाधान यह था कि बच्चे के कंपोनेंट के बाहर से एनजीआईएफ को स्थानांतरित करने के लिए चाइल्ड कंपोनेंट के अंदर एक डिव पर जो html के पूरे सेक्शन को लपेटे हुए है। इस तरह यह तब भी छिपा हुआ था जब इसकी आवश्यकता थी, लेकिन घटक को लोड करने में सक्षम था और मैं इसे माता-पिता में संदर्भित कर सकता था।


लेकिन इसके लिए, आप अपने "दृश्यमान" चर पर कैसे पहुंचे जो कि माता-पिता में था?
दान चेस

1

मैं इसे ठीक सेट सेटाउट जोड़ने के बाद घटक दिखाई दे रहा हूँ

मेरा HTML:

<input #txtBus *ngIf[show]>

मेरे घटक जेएस

@Component({
  selector: "app-topbar",
  templateUrl: "./topbar.component.html",
  styleUrls: ["./topbar.component.scss"]
})
export class TopbarComponent implements OnInit {

  public show:boolean=false;

  @ViewChild("txtBus") private inputBusRef: ElementRef;

  constructor() {

  }

  ngOnInit() {}

  ngOnDestroy(): void {

  }


  showInput() {
    this.show = true;
    setTimeout(()=>{
      this.inputBusRef.nativeElement.focus();
    },500);
  }
}

1

मेरे मामले में, मुझे पता था कि बच्चा घटक हमेशा मौजूद रहेगा, लेकिन काम को बचाने के लिए बच्चे को शुरू करने से पहले राज्य को बदलना चाहता था।

मैं तब तक बच्चे के लिए परीक्षण करना चुनता हूं जब तक वह दिखाई नहीं देता और तुरंत परिवर्तन करता है, जिसने मुझे बच्चे के घटक पर परिवर्तन चक्र बचाया।

export class GroupResultsReportComponent implements OnInit {

    @ViewChild(ChildComponent) childComp: ChildComponent;

    ngOnInit(): void {
        this.WhenReady(() => this.childComp, () => { this.childComp.showBar = true; });
    }

    /**
     * Executes the work, once the test returns truthy
     * @param test a function that will return truthy once the work function is able to execute 
     * @param work a function that will execute after the test function returns truthy
     */
    private WhenReady(test: Function, work: Function) {
        if (test()) work();
        else setTimeout(this.WhenReady.bind(window, test, work));
    }
}

सचेत रूप से, आप अधिकतम संख्या में प्रयास जोड़ सकते हैं या कुछ एमएस विलंब को जोड़ सकते हैं setTimeoutsetTimeoutप्रभावी ढंग से कार्य को लंबित संचालन की सूची के नीचे तक फेंकता है।


0

एक प्रकार का सामान्य दृष्टिकोण:

आप एक विधि बना सकते हैं जो ViewChildतैयार होने तक इंतजार करेगी

function waitWhileViewChildIsReady(parent: any, viewChildName: string, refreshRateSec: number = 50, maxWaitTime: number = 3000): Observable<any> {
  return interval(refreshRateSec)
    .pipe(
      takeWhile(() => !isDefined(parent[viewChildName])),
      filter(x => x === undefined),
      takeUntil(timer(maxWaitTime)),
      endWith(parent[viewChildName]),
      flatMap(v => {
        if (!parent[viewChildName]) throw new Error(`ViewChild "${viewChildName}" is never ready`);
        return of(!parent[viewChildName]);
      })
    );
}


function isDefined<T>(value: T | undefined | null): value is T {
  return <T>value !== undefined && <T>value !== null;
}

उपयोग:

  // Now you can do it in any place of your code
  waitWhileViewChildIsReady(this, 'yourViewChildName').subscribe(() =>{
      // your logic here
  })

0

मेरे लिए समस्या यह थी कि मैं तत्व पर आईडी का उल्लेख कर रहा था।

@ViewChild('survey-form') slides:IonSlides;

<div id="survey-form"></div>

इस तरह के बजाय:

@ViewChild('surveyForm') slides:IonSlides;

<div #surveyForm></div>

0

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


-1

यहाँ कुछ है कि मेरे लिए काम किया है।

@ViewChild('mapSearch', { read: ElementRef }) mapInput: ElementRef;

ngAfterViewInit() {
  interval(1000).pipe(
        switchMap(() => of(this.mapInput)),
        filter(response => response instanceof ElementRef),
        take(1))
        .subscribe((input: ElementRef) => {
          //do stuff
        });
}

इसलिए मैं मूल रूप से हर सेकंड एक जांच सेट करता हूं जब तक कि *ngIfयह सच नहीं हो जाता है और फिर मैं अपना सामान संबंधित करता हूं ElementRef


-3

मेरे लिए काम करने वाला समाधान app.module.ts में घोषणाओं में निर्देश जोड़ना था

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