как запускать события загрузки для элементов внутри компонента html в angular2

Итак, это вопрос 2 в 1.

Во-первых, я пытаюсь запустить функцию, когда загружается элемент в компоненте html. Я пробовал это множеством способов, например: <div [onload]="myFunction()"> однако это приводит к тому, что функция вызывается несколько раз, а точнее 10 раз. Я предполагаю, что это не тот путь, но я недостаточно знаком, чтобы заставить его работать должным образом. Также я хотел бы отправить элемент в качестве параметра. Например, выполнение <div #myDiv (click)="myFunction(myDiv)"> действительно работает, но очевидно, что это не запускается при загрузке указанного элемента. Как правильно здесь, или я обязан сделать querySelector...

Далее следует вопрос, связанный с внедрением ElementRef в компонент. Теперь документы сообщают мне, что использование 'nativeElement ' собственность не совсем путь. Я действительно не понимаю, почему. Наличие ссылки на элемент в вашем компоненте — это хорошо, не так ли? Или я наблюдаю за разделением интересов? Я спрашиваю, потому что, если мой первый вопрос не подходит, я хотел бы использовать эту ссылку на элемент, чтобы выполнить querySelection моих желаемых элементов запуска загрузки в функции ngOnInit класса OnInit.

Вся информация приветствуется, поскольку документы angular2 не совсем полны. Спасибо.

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>


person Ken    schedule 10.02.2016    source источник
comment
Является ли ваш div компонентом сам по себе? или может быть? Также не могли бы вы опубликовать соответствующий код компонента и шаблона   -  person SnareChops    schedule 11.02.2016
comment
Это не так, просто div находится внутри компонента. И да, дайте мне секунду.   -  person Ken    schedule 11.02.2016
comment
Может ли div быть компонентом или это как-то противоречит вашему дизайну? То, о чем вы просите, возможно возможно, но я пытаюсь получить изображение, чтобы порекомендовать лучший способ.   -  person SnareChops    schedule 11.02.2016
comment
div может быть компонентом, но я бы хотел этого избежать.   -  person Ken    schedule 11.02.2016
comment
@SnareChops Я добавил вырезанный код.   -  person Ken    schedule 11.02.2016
comment
@ Кен, ты пробовал это? angular.io/docs/ts/latest/api/core/ Запрос-var.html   -  person Langley    schedule 11.02.2016
comment
@Langley У меня нет, очень полезно, но не совсем то, на что я надеялся ...   -  person Ken    schedule 11.02.2016


Ответы (3)


Информацию о загрузке событий см. в этой статье начиная с ошибки новичка №2.

Для общих событий я обнаружил, что EventEmitter полезен как способ для дочерних компонентов (настраиваемых тегов разметки) сообщать родительскому компоненту о дочерних событиях. В дочернем элементе создайте пользовательское событие (переменная класса, украшенная @Output() ), которое будет .emit() всякий раз, когда вы определите, и может включать параметры вашего EventEmitter, указанного <data type>. Затем родитель может обработать пользовательское событие и получить доступ к параметрам, которые вы связали в $event. Я использую файлы быстрого запуска Angular 2.

Дочерний сценарий:

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

Родительская разметка:

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

Родительский сценарий:

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
  }

}

Примечание. вы также можете попробовать EventEmitter<MyChildComponent> с .emit(this)

person BeatriceThalo    schedule 25.05.2016

Вы можете получить экземпляр вашего div с помощью Query, а затем в ngOnInit вызвать метод registerDropdown и передать nativeElement из 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);
  }
}
person SnareChops    schedule 10.02.2016
comment
Это, однако, использует ElementRef, где мне придется использовать «nativeElement». Это желательно? - person Ken; 11.02.2016
comment
Предупреждение об ElementRef относится к необходимости запуска в браузере. Это не проблема, если вы не планируете выполнять рендеринг на стороне сервера. - person SnareChops; 11.02.2016
comment
Раскрывающийся список регистров позже будет вызываться для нескольких элементов, то есть мне придется запрашивать каждый элемент отдельно. Неужели нельзя сделать реестр в html? - person Ken; 11.02.2016
comment
рендеринга на стороне сервера нет, только в браузерах. - person Ken; 11.02.2016
comment
QueryList возвращает список совпадающих элементов. Вы должны иметь возможность иметь несколько экземпляров, а затем просто вызывать registerDropdown для каждого из них. Angular может получить доступ к HTML, но HTML не может получить доступ к Angular из-за того, что angular не содержит глобальной ссылки на window - person SnareChops; 11.02.2016
comment
должен ли я объявлять каждый элемент как равную переменную (имеется в виду: могу ли я все называть их #someVarName). будет ли это работать, я не хочу запрашивать каждый элемент отдельно. - person Ken; 11.02.2016
comment
понижено за зависимость от jQuery - я пытаюсь найти способ Angular 2 сделать это... - person Paul Nelligan; 12.05.2016

При дальнейшем чтении кажется, что внедрение шпиона — лучший способ добиться этого:

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

person Paul Nelligan    schedule 19.05.2016