Вместо того, чтобы вводить 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.
читать
Если есть компонент и директивы, read
параметр позволяет указать, какой экземпляр должен быть возвращен.
Например 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));
}
прямой доступ к 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);
}
}
получить произвольный проектируемый контент
См. Доступ к включенному контенту
input
также естьElementRef
, но вы получаете ссылку на элемент, который вам действительно нужен, вместо того, чтобы запрашивать его у хостаElementRef
.ElementRef
просто отлично. Также использованиеElementRef.nativeElement
сRenderer
хорошо. Что обескураживает, так этоElementRef.nativeElement.xxx
прямой доступ к свойствам .ElementRef.nativeElement)
Прямой доступ к DOM (то есть доступ к свойствам и методам не позволяет вам использовать рендеринг на стороне сервера Angulars и функцию WebWorker (я не знаю, нарушает ли это также готовящийся к выходу компилятор шаблонов в автономном режиме - но я полагаю, что нет).@ViewChild('myObj', { read: ElementRef }) myObj: ElementRef;
Вы можете получить дескриптор элемента DOM
ElementRef
, вставив его в конструктор вашего компонента:Документы: https://angular.io/docs/ts/latest/api/core/index/ElementRef-class.html
источник
ElementRef
как ушел.ElementRef
доступно (опять?).this.element.nativeElement.querySelector('#someElementId')
и передать ElementRef в конструктор следующим образом.private element: ElementRef,
Импортироватьimport { ElementRef } from '@angular/core';
Обновлен пример для работы с последней версией
Для более подробной информации о нативном элементе, здесь
источник
Angular 4+ : используйте
renderer.selectRootElement
с селектором CSS для доступа к элементу.У меня есть форма, которая первоначально отображает ввод электронной почты. После ввода электронного письма форма будет расширена, чтобы они могли продолжать добавлять информацию, относящуюся к их проекту. Однако, если они не являются существующим клиентом, форма будет содержать адресный раздел над разделом с информацией о проекте.
На данный момент часть ввода данных не разбита на компоненты, поэтому разделы управляются с помощью директив * ngIf. Мне нужно установить фокус на поле заметок проекта, если это существующий клиент, или поле имени, если они новые.
Я попробовал решения безуспешно. Тем не менее, обновление 3 в этом ответе дало мне половину возможного решения. Другая половина пришла от ответа MatteoNY в этой теме. Результат таков:
Поскольку единственное, что я делаю, это устанавливаю фокус на элементе, мне не нужно заниматься обнаружением изменений, поэтому я могу фактически выполнить вызов за
renderer.selectRootElement
пределами Angular. Поскольку мне нужно дать время новым секциям на рендеринг, секция элемента обернута в тайм-аут, чтобы позволить потокам рендеринга наверстать упущенное перед попыткой выбора элемента. После того, как все это настроено, я могу просто вызвать элемент с помощью основных селекторов CSS.Я знаю, что этот пример в основном касался события фокуса, но мне трудно, чтобы его нельзя было использовать в других контекстах.
источник
Для людей, пытающихся захватить экземпляр компонента внутри
*ngIf
или*ngSwitchCase
, вы можете выполнить этот трюк.Создать
init
директиву.Экспортируйте свой компонент с именем, таким как
myComponent
Используйте этот шаблон, чтобы получить экземпляр
ElementRef
ANDMyComponent
Используйте этот код в TypeScript
источник
импортировать
ViewChild
декоратор из@angular/core
, вот так:HTML-код:
Код TS:
теперь вы можете использовать объект myForm для доступа к любому элементу в классе.
Source
источник
источник
inputTxt
.Примечание : Это не относится к угловому 6 и выше,
ElementRef
сталElementRef<T>
сT
обозначающим типомnativeElement
.Я хотел бы добавить, что если вы используете
ElementRef
, как рекомендовано всеми ответами, то вы сразу же столкнетесь с проблемой, котораяElementRef
имеет ужасное объявление типа, которое выглядит какэто глупо в среде браузера, где nativeElement является
HTMLElement
.Чтобы обойти это, вы можете использовать следующую технику
источник
item
потребности быть ElementRef, даже если вы устанавливаете его на другой ElementRef:let item:ElementRef, item2:ElementRef; item = item2; // no can do.
. Очень запутанно. Но это хорошо:let item:ElementRef, item2:ElementRef; item = item2.nativeElement
из-за реализации, которую вы указали.let item: ElementRef, item2: ElementRef; item = item2
терпит неудачу из-за анализа определенного присваивания. Ваш второй сбой по тем же причинам, но оба успешны, еслиitem2
инициализируются по рассмотренным причинам (или в качестве полезной быстрой проверки назначаемости, которую мы можем использоватьdeclare let
здесь) Независимо от того, действительно стыдно видетьany
на публичном API, как это.чтобы получить ближайшего родственника, используйте это
источник
Выбор целевого элемента из списка. Легко выбрать конкретный элемент из списка тех же элементов.
код компонента:
HTML-код:
Код CSS:
источник
Минимальный пример для быстрого использования:
#inputEl
на<input>
метке.ngAfterViewInit
хуке жизненного цикла.Замечания:
Если вы хотите манипулировать элементами DOM, используйте API Renderer2 вместо прямого доступа к элементам. Разрешение прямого доступа к DOM может сделать ваше приложение более уязвимым для атак XSS
источник