how do I fire onload events for elements within co

2019-04-07 11:14发布

So this is a 2 in 1 question.

First, I am trying to fire a function when an element, within a components html, loads. I tried it numerous ways, like: <div [onload]="myFunction()"> this however results in the function being called multiple times, 10 to be exact. My guess is this is not the way to go, but I am not familiar enough to get it working properly. Also I would like to send the element along as a parameter. For example doing <div #myDiv (click)="myFunction(myDiv)"> does work, but obviously this isn't fired onload of said element. Whats the proper way here, or am I obligated to do a querySelector...

Next is a question involving the injection of the ElementRef within the component. Now, the docs tell me that using the 'nativeElement' property is not quite the way to go. I don't really understand why. Having a reference to the element in your component is a good thing, is it not? Or am I overseeing a separation of concern thing? I am asking because if my first question is not an option, I would like to use this element reference to do a querySelection of my desired onload firing elements in the ngOnInit function of the OnInit class.

All information is welcome, seeing the angular2 docs are not quite complete. Thank you.

export class HomeComponent implements OnInit
{
    public categories: Category[];
    public items: Item[];

    constructor
    (
        public element: ElementRef,
        private _categoryService: CategoryService,
        private _itemService: ItemService,
        private _router: Router
    ){}

    public registerDropdown(element:HTMLElement): void
    {
        console.log(element);
    }

    private getCategories(): void
    {
        this._categoryService.getAll().then((categories:Category[])=> this.categories = categories);
    }

    private getItems(): void
    {
        this._itemService.getAll().then((items:Item[])=> this.items = items);
    }

    public ngOnInit(): any
    {
        this.getCategories();
        this.getItems();
    }
}
<div id="home">

    <div id="search">
        <div class="container">

            <!-- div in question, the [ngModel] is a shot in the dark -->
            <div #myDiv class="dropdown category" [ngModel]="registerDropdown(myDiv)">
                <span class="placeholder">Selecteer categorieën</span>
                <div class="the-drop">
                    <ul class="ul">
                        <li *ngFor="#category of categories">
                            <input type="checkbox" />{{category.long}}
                        </li>
                    </ul>
                </div>
            </div>
          
        </div>
    </div>
  
</div>

3条回答
走好不送
2楼-- · 2019-04-07 11:31

For loading events, check out this article starting at rookie Mistake #2.

For general events, I found EventEmitter to be useful as a way for child components (custom markup tags) to tell the parent component about the child's events. In the child, create a custom event (a class variable decorated with @Output() ) which will .emit() whenever you determine, and can include parameters of your EventEmitter's specified <data type>. Then the parent can handle the custom event and access the parameters that you bundled within $event. I am using the Angular 2 quickstart files.

Child Script:

import {Component, Output, EventEmitter} from '@angular/core';
@Component({
  selector: 'my-child',
  templateUrl: 'app/my-child.component.html'
})
export class MyChildComponent {
  @Output() childReadyEvent: EventEmitter<string> = new EventEmitter();

  ngOnInit(){
    //do any lines of code to init the child
    console.log("this executes second");
    //then finally,
    this.childReadyEvent.emit("string from child");        
  }
}

Parent Markup:

<h3>I'm the parent</h3>
<my-child (childReadyEvent)="parentHandlingFcn($event)"></my-child>

Parent Script:

import {Component} from '@angular/core';
import {MyChildComponent} from './my-child.component';

@Component({
  selector: 'my-parent',
  templateUrl: 'app/my-parent.component.html',
  directives: [MyChildComponent]
})
export class MyParentComponent {

  ngOnInit(){
    console.log("this executes first");
  }

  parentHandlingFcn(receivedParam: string) {
    console.log("this executes third, with " + receivedParam); //string from child
  }

}

Note: you could also try EventEmitter<MyChildComponent> with .emit(this)

查看更多
我只想做你的唯一
3楼-- · 2019-04-07 11:39

On further reading, it seems that implementing a Spy is the best way to achieve this:

https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#spy

查看更多
迷人小祖宗
4楼-- · 2019-04-07 11:55

You can grab an instance of your div using Query and then in the ngOnInit trigger the registerDropdown method and pass in the nativeElement from the QueryList<ElementRef>

export class HomeComponent implements OnInit{
  public categories: Category[];
  public items: Item[];

  constructor
  (
    public element: ElementRef,
    private _categoryService: CategoryService,
    private _itemService: ItemService,
    private _router: Router,
    @Query('myDiv') private elList: QueryList<ElementRef>
  ){}

  public registerDropdown(element:HTMLElement): void
  {
    console.log(element);
  }

  ...

  public ngOnInit(): any
  {
    this.getCategories();
    this.getItems();
    this.registerDropdown(elList.first.nativeElement);
  }
}
查看更多
登录 后发表回答