কৌণিক 2 @ ভিউচিল্ড টীকাটি অনির্ধারিত returns


241

আমি কৌনিক 2 শিখার চেষ্টা করছি।

আমি @ ভিউচিল্ড এনটোটেশন ব্যবহার করে পিতামাতার উপাদান থেকে কোনও সন্তানের অংশে অ্যাক্সেস করতে চাই ।

কোডের কয়েকটি লাইন এখানে:

ইন 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>

ফিল্টারটাইলস এইচটিএমএল টেমপ্লেটটি সঠিকভাবে আইকো -ফিল্টার-টাইলস ট্যাগে লোড করা হয়েছে (প্রকৃতপক্ষে আমি শিরোনামটি দেখতে সক্ষম হয়েছি)।

দ্রষ্টব্য: বডি কনটেন্ট ক্লাসটি ডায়নামিক কমপোনেটলোডার ব্যবহার করে অন্য টেমপ্লেটের (বডি) ভিতরে ইনজেকশনের ব্যবস্থা করা হয়েছে: dcl.loadAsRoot (বডি-কনটেন্ট, '# আইকো-বডি-কনটেন্ট', ইনজেক্টর):

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এবং অবশ্যই যখন আমি "টাইলস" অ্যারের ভিতরে কোনও কিছুর চেষ্টা করি তখন ব্যতিক্রম পাই: '"অপরিজ্ঞাত" জন্য কোনও সম্পত্তি টাইলস নেই

আরও একটি জিনিস: ফিল্টারটাইলস উপাদানটি সঠিকভাবে লোড হয়েছে বলে মনে হচ্ছে, যেহেতু আমি এর জন্য এইচটিএমএল টেমপ্লেটটি দেখতে সক্ষম হয়েছি।

যেকোনো পরামর্শ? ধন্যবাদ


সঠিক দেখাচ্ছে। টেমপ্লেট সহ কিছু হতে পারে তবে এটি আপনার প্রশ্নের মধ্যে অন্তর্ভুক্ত নয়।
Gternter Zöchbauer

1
গন্টারের সাথে একমত আমি আপনার কোড এবং সাধারণ সম্পর্কিত টেম্পলেটগুলির সাথে একটি প্লঙ্কার তৈরি করেছি এবং এটি কাজ করে। এই লিঙ্কটি দেখুন: plnkr.co/edit/KpHp5Dlmppzo1LXcutPV?p= পূর্বরূপ দেখুন । আমাদের টেমপ্লেটগুলি প্রয়োজন ;-)
থিয়েরি টেম্পিলার

1
ftকনস্ট্রাক্টরে সেট করা হবে না, তবে একটি ক্লিক ইভেন্ট হ্যান্ডলারটিতে এটি ইতিমধ্যে সেট করা হবে।
গন্টার জ্যাচবাউর

5
আপনি ব্যবহার করছেন loadAsRoot, যার পরিবর্তন সনাক্তকরণের সাথে একটি জ্ঞাত সমস্যা রয়েছে। ব্যবহার নিশ্চিত করার চেষ্টা করুন loadNextToLocationবা loadIntoLocation
এরিক মার্টিনেজ

1
সমস্যা ছিল loadAsRoot। একবার প্রতিস্থাপনের সাথে loadIntoLocationসমস্যার সমাধান হয়ে গেল। আপনি যদি উত্তর হিসাবে আপনার মন্তব্য করেন তবে আমি এটি গ্রহণযোগ্য হিসাবে চিহ্নিত করতে পারি
Andrea Ialenti

উত্তর:


373

আমারও একই সমস্যা ছিল এবং আমি ভেবেছিলাম যে অন্য কেউ যদি একই ভুল করে তবে আমি পোস্ট করব। প্রথমত, একটি বিষয় বিবেচনা করতে হবে 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
    }
}

আশা করি এইটি কাজ করবে.

সম্পাদনা নীচে @ অ্যাশগ
দ্বারা উল্লিখিত হিসাবে , এর পরিবর্তে একটি সমাধান ব্যবহার করা উচিত ।@ViewChildren@ViewChild


9
@কেনেকসওয়েল তাই সমস্যা সমাধানের আরও ভাল উপায় খুঁজে পেয়েছেন? আমিও একই সমস্যার মুখোমুখি হয়েছি। আমার কাছে অনেক * এনজিআইফ রয়েছে যদি সেই উপাদানটি সমস্ত সত্যের পরে একমাত্র হয় তবে আমার উপাদানটির রেফারেন্সটি দরকার।
এটির

4
আমি দেখতে পেয়েছি যে এনজিএফ ব্যবহার করা হলে শিশু উপাদানটি এনজিএফটারভিউআইনিট () এ 'অপরিজ্ঞাপিত'। আমি দীর্ঘ সময়সীমা স্থাপনের চেষ্টা করেছি কিন্তু এখনও কার্যকর হয়নি। তবে, সন্তানের উপাদানগুলি পরে উপলব্ধ (যেমন ইভেন্টগুলির ক্লিকের প্রতিক্রিয়া হিসাবে)। যদি আমি এনজিআইএফ ব্যবহার না করি এবং এটি এনজিএফটারভিউআইনিট () এ প্রত্যাশিত হিসাবে সংজ্ঞায়িত করা হয়েছে। পিতামাতা / শিশু যোগাযোগের আরও কিছু বিষয় এখানে রয়েছে কৌণিক.আইও
ম্যাথু হেগার্টি

3
আমি এর পরিবর্তে বুটস্ট্র্যাপ ngClass+ hiddenক্লাস ব্যবহার করেছি ngIf। কাজ করেছে। ধন্যবাদ!
রহমতুল্লাহ এম

9
এটি সমস্যার সমাধান করে না, নীচের সমাধানটি ব্যবহার করুন @ ভিউ চিলড্রেন ব্যবহার করে চাইল্ড কন্ট্রোলের উপলব্ধ হয়ে
ওঠার পরে

20
এটি ঠিক "ইস্যু" প্রমাণ করে, তাই না? এটি কোনও সমাধান পোস্ট করে না।
মিগুয়েল রিবেইরো

145

পূর্বে উল্লিখিত ইস্যুটি 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
আপনি যদি একটি # টিউমার 2 এলিমেন্টের পরিবর্তে আপনার # সার্চগ্রিডের ট্যাগটি কোনও এইচটিএমএল উপাদানটিতে রাখতে চান তবে আপনি এটি কীভাবে করবেন? (উদাহরণস্বরূপ, <ডিভ # সার্চগ্রিড> </div> এবং এটি কোনও * এনজিআইএফ ব্লকের ভিতরে রয়েছে?
ভার্ন জেনসেন

1
এটি আমার ব্যবহারের ক্ষেত্রে সঠিক উত্তর! ধন্যবাদ এনজিআইএফ =
ফ্রোজেন_বাইট

1
এটি আজাক্স প্রতিক্রিয়াগুলির উপর নিখুঁতভাবে কাজ করে, এখন *ngIfকাজ করে এবং রেন্ডার করার পরে আমরা ডায়নামিক উপাদানগুলি থেকে একটি এলিমেন্টরিফ সংরক্ষণ করতে পারি।
elporfirio

4
এটিকে একটি সাবস্ক্রিপশনে বরাদ্দ করতে ভুলবেন না এবং তারপরে সাবস্ক্রাইব করুন
tam.teixeira

63

আপনি একটি সেটার ব্যবহার করতে পারেন @ViewChild()

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

আপনার যদি এনজিআইএফ র‌্যাপার থাকে তবে সেটারটি অপরিজ্ঞাত করে কল করা হবে, এবং আবার একবার রেফারেন্স সহ এনজিআইএফ এটি রেন্ডার করতে দেয়।

আমার বিষয়টি যদিও অন্য কিছু ছিল। আমি আমার অ্যাপ্লিকেশনগুলির মডেলগুলিতে আমার "ফিল্টার টাইলস" মডিউলটি অন্তর্ভুক্ত করি নি। টেমপ্লেটটি কোনও ত্রুটি ফেলেনি তবে রেফারেন্সটি সর্বদা সংজ্ঞায়িত ছিল।


3
এটি আমার পক্ষে কাজ করছে না - আমি প্রথম অপরিবর্তিত, তবে দ্বিতীয় কল ডাব্লু / রেফারেন্স পাই না। অ্যাপটি একটি এনজি 2 ... এই এনজি 4 + বৈশিষ্ট্যটি কী?
জে কামিন্স

@ জায়ে আমি বিশ্বাস করি এটি কারণ আপনি এই ক্ষেত্রে কৌনিক সাথে উপাদানটি নিবন্ধভুক্ত করেন নি FilterTiles। এর আগেও আমি এই সমস্যার মুখোমুখি হয়েছি।
সংসদ

1
কৌণিক 8 ওয়ার্কস HTML উপাদান মত টীকা উপর #paginator ব্যবহার@ViewChild('paginator', {static: false})
Qiteq

1
এটি কি ভিউচিল্ড পরিবর্তনের জন্য একটি কলব্যাক?
ইয়াসের ন্যাসিমেণ্টো

24

এটি আমার পক্ষে কাজ করেছে।

উদাহরণস্বরূপ, 'আমার-উপাদান' নামক আমার উপাদানটি এমনভাবে * ngIf = "showMe" ব্যবহার করে প্রদর্শিত হয়েছিল:

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

সুতরাং, যখন উপাদানটি ইনিশিয়েল করা হবে তখন "শোএমই" সত্য হওয়া অবধি অংশটি প্রদর্শিত হবে না। সুতরাং, আমার @ ভিউচিল্ড রেফারেন্সগুলি সমস্ত অপরিজ্ঞাত ছিল।

এখানেই আমি @ ভিউচিল্ডেন এবং কোয়েরিস্ট ব্যবহার করেছি যা এটি ফিরে আসে। দেখুন QueryList উপর কৌণিক নিবন্ধ এবং একটি @ViewChildren ব্যবহার ডেমো

@ ভিউচিল্ডারেন ফেরত পাওয়া ক্যোরিলিস্টটি ব্যবহার করতে পারেন এবং নীচে উল্লিখিত হিসাবে rxjs ব্যবহার করে রেফারেন্সড আইটেমগুলিতে যে কোনও পরিবর্তনের জন্য সাবস্ক্রাইব করতে পারেন। @ ভিউচিল্ডের এই ক্ষমতা নেই।

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
প্রকৃতপক্ষে আপনার সমাধানটি এখনও পর্যন্ত তালিকাভুক্ত সেরা পদ্ধতির বলে মনে হচ্ছে। দ্রষ্টব্য আমাদের মাথায় রাখতে হবে যে শীর্ষ solution৩ টি সমাধানটি এখনই অগ্রাহ্য করা হয়েছে ... নির্দেশনার পর থেকে: [...] ঘোষণাটি আর কৌণিক 4 তে সমর্থিত নয় IOW এটি
কৌনিক

5
সাবস্ক্রাইব, বা ব্যবহার করতে ভুলবেন না .take(1).subscribe(), তবে দুর্দান্ত উত্তর, আপনাকে অনেক ধন্যবাদ!
ব্লেয়ার কনলি

2
দুর্দান্ত সমাধান। আমি এনজিএন্টারচেনিজ () এর পরিবর্তে এনজিএফটারভিউআইনিট () এর রেফ পরিবর্তনগুলিতে সদস্যতা নিয়েছি। তবে আমাকে এক্সপ্রেশন
চ্যাঞ্জডএফটারচেকড

এটি প্রকৃত সমাধান হিসাবে চিহ্নিত করা উচিত। অনেক ধন্যবাদ!
প্ল্যাটজারশ

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";
    }
  }
....

একটি পৃষ্ঠা আছে যেখানে আইটেমের তালিকা একটি সারণীতে প্রদর্শিত হয়, বা সম্পাদনা আইটেমটি প্রদর্শিত হয় শোললিস্ট ভেরিয়েবলের মানের উপর ভিত্তি করে। বিরক্তিকর কনসোল ত্রুটি থেকে মুক্তি পেয়েছেন [শৈলী.ডিসপ্লে] = "! শোলিস্ট", * ngIf = "! শোলিস্ট" এর সাথে একত্রিত করে।
রাজনওয়োন

9

আমার সমস্যার সমাধান কী তা নিশ্চিত করা staticছিল false

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

staticনিষ্ক্রিয় হওয়ার সাথে সাথে নির্দেশটি পরিবর্তিত @ViewChildহলে রেফারেন্সটি কৌনিক দ্বারা আপডেট হয় *ngIf


1
এটি প্রায় একটি নিখুঁত উত্তরদাতা, কেবল উল্লেখযোগ্য হ'ল নালাগুলির মানগুলি পরীক্ষা করার জন্য একটি ভাল অভ্যাস, সুতরাং আমরা এই জাতীয় কিছু দিয়ে শেষ করি: @ ভিউচিল্ড (ক্লারফর্ম, {স্ট্যাটিক: মিথ্যা}) সেট ক্লারফর্ম (ক্লারফর্ম: ক্লারফর্ম) {যদি (clrForm) {this.clrForm = clrForm; }};
ক্লাউস ক্লিন

আমি অনেক কিছুই চেষ্টা করেছিলাম এবং অবশেষে এই জিনিসটিকে অপরাধী হিসাবে পেয়েছি।
মণীশ শর্মা

8

আমার এটির সমাধানটি প্রতিস্থাপন করা *ngIf ছিল [hidden]। ডাউনসাইডটি ছিল কোড ডিওমে সমস্ত শিশু উপাদান উপস্থিত ছিল। কিন্তু আমার প্রয়োজনীয়তা জন্য কাজ।


5

আমার ক্ষেত্রে, আমার একটি ইনপুট ভেরিয়েবল সেটার ব্যবহার করে ছিল ViewChildএবং এটি ViewChildএকটি *ngIfনির্দেশকের অভ্যন্তরে ছিল , সুতরাং সেটারটি রেন্ডারের আগে এটি অ্যাক্সেস করার চেষ্টা করছিল *ngIf(এটি ছাড়া ভাল কাজ করবে *ngIf, তবে এটি সর্বদা সেট করা থাকলে কাজ করবে না) সাথে সত্য *ngIf="true")।

সমাধানের জন্য, আমি আরএক্সজেএস দেখেছি যাতে 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();
  })
}

শেষ পর্যন্ত, ভিউচিল্ডের উল্লেখগুলি এই ফাংশনটি ব্যবহার করে তা নিশ্চিত করুন।

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

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

1
এটি সমস্ত সেটটাইম আউটসের চেয়ে অনেক বেশি ভাল সমাধান
লিয়াম

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
যদি সমস্যাটি আমার মতো হয় তবে সদৃশ করতে আপনাকে <ফিল্টার> </filter> এর আশেপাশে টেম্পলেটে একটি * এনজিআইফ লাগাতে হবে .. সম্ভবত এনজিআইফ যদি মিথ্যা ফেরত দেয় তবে ভিউচিল্ড তারযুক্ত হয় না এবং নাল ফিরে দেয়
ড্যান চেজ

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অবিলম্বে কার্যকর করা হয়েছিল (উদাহরণস্বরূপ 0 মিমি)


1

আমার এই সমাধানটি হ'ল এইচটিএমএল এর পুরো বিভাগটি মোড়ানো একটি ডিভের উপর শিশু উপাদানটির বাইরে থেকে এনজিআইফ সরিয়ে নেওয়া হয়েছিল component এটি হওয়ার দরকার পরে এটি এখনও লুকিয়ে ছিল, তবে উপাদানটি লোড করতে সক্ষম হয়েছিল এবং আমি এটি পিতামাতার মধ্যে উল্লেখ করতে পারি।


তবে তার জন্য, আপনি কীভাবে পিতামাতার মধ্যে থাকা আপনার "দৃশ্যমান" ভেরিয়েবলটি পেলেন?
ড্যান চেইস

1

আমি দৃ fix় দৃশ্যমান উপাদান সেট পরে সেটটাইমআউট যুক্ত করে এটি ঠিক করেছি

আমার এইচটিএমএল:

<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 মধ্যে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.