Как я могу выбрать элемент в шаблоне компонента?



кто-нибудь знает, как получить элемент, определенный в шаблоне компонента? Полимер делает его очень легко с $ и $$.



мне просто интересно, как это сделать в Angular.



возьмите пример из учебника:



import {Component} from '@angular/core'

@Component({
selector:'display'
template:`
<input #myname(input)="updateName(myname.value)"/>
<p>My name : {{myName}}</p>
`

})
export class DisplayComponent {
myName: string = "Aman";
updateName(input: String) {
this.myName = input;
}
}


как мне ухватиться за ссылку p или input элемент из определения класса?

578   10  

10 ответов:

вместо введения ElementRef и с помощью querySelector или аналогичного оттуда, декларативный способ может быть использован вместо того, чтобы получить доступ к элементам в представлении напрямую:

<input #myname>
@ViewChild('myname') input; 

элемент

ngAfterViewInit() {
  console.log(this.input.nativeElement.value);
}

StackBlitz пример

  • @ViewChild() поддерживает директиву или тип компонента в качестве параметра, или имя (строка) переменной шаблона.
  • @ViewChildren() также поддерживает список имен, разделенных запятыми (в настоящее время пробелы не допускаются @ViewChildren('var1,var2,var3')).
  • @ContentChild() и @ContentChildren() сделайте то же самое, но в свете DOM (<ng-content> проектируемых элементов).

потомки

@ContentChildren() это единственный, который позволяет также запрашивать потомков

@ContentChildren(SomeTypeOrVarName, {descendants: true}) someField; 

{descendants: true} должно быть по умолчанию, но не в 2.0.0 final и это считается ошибка
Это было исправлено в 2.0.1

читать

если есть компонент и директивы ViewContainerRef это требуется для динамически создаваемых компонентов, а не по умолчанию ElementRef

@ViewChild('myname', { read: ViewContainerRef }) target;

подписаться на изменения

хотя просмотр детей задается только тогда, когда ngAfterViewInit() вызывается и содержание детей устанавливаются только тогда, когда ngAfterContentInit() называется, если вы хотите подписаться на изменения результата запроса, это должно быть сделано в ngOnInit()

https://github.com/angular/angular/issues/9689#issuecomment-229247134

@ViewChildren(SomeType) viewChildren;
@ContentChildren(SomeType) contentChildren;

ngOnInit() {
  this.viewChildren.changes.subscribe(changes => console.log(changes));
  this.contentChildren.changes.subscribe(changes => console.log(changes));
}

direct DOM доступ

может запрашивать только элементы DOM, но не компоненты или экземпляры директив:

export class MyComponent {
  constructor(private elRef:ElementRef) {}
  ngAfterViewInit() {
    var div = this.elRef.nativeElement.querySelector('div');
    console.log(div);
  }

  // for transcluded content
  ngAfterContentInit() {
    var div = this.elRef.nativeElement.querySelector('div');
    console.log(div);
  }
}

получить произвольное проецируемое содержимое

посмотреть доступ к транскрипции контента

вы можете получить дескриптор элемента DOM через ElementRef путем введения его в конструктор вашего компонента:

constructor(myElement: ElementRef) { ... }

Docs:https://angular.io/docs/ts/latest/api/core/index/ElementRef-class.html

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

@Component({
  selector:'display',
  template:`
   <input (input)="updateName($event.target.value)">
   <p> My name : {{ myName }}</p>
  `
})
class DisplayComponent implements OnInit {
  constructor(public element: ElementRef) {
    this.element.nativeElement // <- your direct element reference 
  }
  ngOnInit() {
    var el = this.element.nativeElement;
    console.log(el);
  }
  updateName(value) {
    // ...
  }
}

пример обновлен для работы с последней версией

для получения более подробной информации о родную стихию, здесь

угловые 4+: Используйте renderer.selectRootElement с селектором CSS для доступа к элементу.

у меня есть форма, которая изначально отображает ввод электронной почты. После ввода сообщения электронной почты форма будет расширена, чтобы они могли продолжать добавлять информацию, касающуюся их проекта. Однако, если они не существующий клиент, форма будет включать в себя раздел Адреса над разделом информации о проекте.

на данный момент часть ввода данных не была разбиты на компоненты, поэтому разделы управляются с помощью директив *ngIf. Мне нужно установить фокус на поле примечания к проекту, если они являются существующим клиентом, или поле имени, если они новые.

Я пробовал решения без успеха. Тем не менее, обновление 3 в этой ответ дал мне половину возможного решения. Другая половина исходила от ответа Маттеони в этой нить. В результате получается следующее:

import { NgZone, Renderer } from '@angular/core';

constructor(private ngZone: NgZone, private renderer: Renderer) {}

setFocus(selector: string): void {
    this.ngZone.runOutsideAngular(() => {
        setTimeout(() => {
            this.renderer.selectRootElement(selector).focus();
        }, 0);
    });
}

submitEmail(email: string): void {
    // Verify existence of customer
    ...
    if (this.newCustomer) {
        this.setFocus('#firstname');
    } else {
        this.setFocus('#description');
    }
}

Так как единственное, что я выполнение-это установка фокуса на элементе, мне не нужно беспокоиться об обнаружении изменений, поэтому я могу фактически запустить вызов renderer.selectRootElement внешний угловой. Поскольку мне нужно дать новым разделам время для рендеринга, раздел элемента обернут в тайм-аут, чтобы позволить потокам рендеринга догнать время до попытки выбора элемента. После того, как все это настроено, я могу просто вызвать элемент с помощью базовых селекторов CSS.

Я знаю, что этот пример касался в первую очередь фокуса событие, но мне трудно, что это не может быть использовано в других контекстах.

для людей, пытающихся захватить экземпляр компонента внутри *ngIf или *ngSwitchCase, вы можете следовать этому трюку.

создать

импортируйте декоратор ViewChild из @angular / core, например:

<form #f="ngForm"> ... </form>



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

    class TemplateFormComponent {

      @ViewChild('f') myForm: any;
    .
    .
    .
    }

теперь вы можете использовать объект 'myForm' для доступа к любому элементу в нем в классе.

источник: https://codecraft.tv/courses/angular/forms/template-driven/

 */
import {Component,ViewChild} from '@angular/core' /*Import View Child*/

@Component({
    selector:'display'
    template:`

     <input #myname (input) = "updateName(myname.value)"/>
     <p> My name : {{myName}}</p>

    `
})
export class DisplayComponent{
  @ViewChild('myname')inputTxt:ElementRef; /*create a view child*/

   myName: string;

    updateName: Function;
    constructor(){

        this.myName = "Aman";
        this.updateName = function(input: String){

            this.inputTxt.nativeElement.value=this.myName; 

            /*assign to it the value*/
        };
    }
}

Я хотел бы добавить, что если вы используете ElementRef, Как рекомендуется всеми ответами, то вы сразу же столкнетесь с проблемой, что ElementRef имеет ужасное объявление типа, которое выглядит как

export declare class ElementRef {
  nativeElement: any;
}

это глупо в среде браузера, где nativeElement является HTMLElement.

чтобы обойти это, вы можете использовать следующую технику

import {Inject, ElementRef as ErrorProneElementRef} from '@angular/core';

interface ElementRef {
  nativeElement: HTMLElement;
}

@Component({...}) export class MyComponent {
  constructor(@Inject(ErrorProneElementRef) readonly elementRef: ElementRef) { }
}

чтобы получить непосредственного следующего брата, используйте это

event.source._elementRef.nativeElement.nextElementSibling

выбор элемента из списка. Легко выбрать определенный элемент из списка одинаковых элементов.

компонент код:

export class AppComponent {
  title = 'app';

  listEvents = [
    {'name':'item1', 'class': ''}, {'name':'item2', 'class': ''},
    {'name':'item3', 'class': ''}, {'name':'item4', 'class': ''}
  ];

  selectElement(item: string, value: number) {
    console.log("item="+item+" value="+value);
    if(this.listEvents[value].class == "") {
      this.listEvents[value].class='selected';
    } else {
      this.listEvents[value].class= '';
    }
  }
}

HTML-код:

<ul *ngFor="let event of listEvents; let i = index">
   <li  (click)="selectElement(event.name, i)" [class]="event.class">
  {{ event.name }}
</li>

css код:

.selected {
  color: red;
  background:blue;
}

Comments

    Ничего не найдено.