angular dom
The @ViewChild
and @ViewChildren
decorators in Angular provide a way to access and manipulate DOM elements, directives and components. In this tutorial, we'll see an Angular 8 example of how to use the two decorators.
Angular中的@ViewChild
和@ViewChildren
装饰器提供了一种访问和操作DOM元素,指令和组件的方式。 在本教程中,我们将看到一个如何使用两个装饰器的Angular 8示例。
You can use ViewChild
if you need to query one element from the DOM and ViewChildren
for multiple elements.
如果您需要查询DOM中的一个元素,而ViewChildren
需要多个元素,则可以使用ViewChild
。
We'll be using an online development IDE available from https://stackblitz.com/ so you don't need to set up your local development machine for Angular at this point.
我们将使用可从https://stackblitz.com/获得的在线开发IDE,因此此时您无需为Angular设置本地开发机器。
Head over to Stackblitz, sign in with your GitHub account and choose an Angular workspace:
前往Stackblitz,使用您的GitHub帐户登录并选择Angular工作区:
You should be presented with an online IDE with an Angular 8 project
应该为您提供带有Angular 8项目的在线IDE
Our Angular project contains the usual App
component and a child component called HelloComponent
and defined in the src/app/hello.component.ts
file with the following code:
我们的Angular项目包含常用的App
组件和一个名为HelloComponent
的子组件,并在src/app/hello.component.ts
文件中使用以下代码定义:
import { Component, Input } from '@angular/core';@Component({selector: 'hello',template: `<h1>Hello !</h1>`,styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent {@Input() name: string;
}
The component accepts a name
property and uses an inline template which simply displays the value passed via the name property from the parent component.
该组件接受一个name
属性,并使用一个内联模板,该模板仅显示通过name属性从父组件传递的值。
In the component decorator, we used hello as the selector for the component so in the the HTML template of the App
component defined in the src/app/app.component.html
file, we include the child component using the following code:
在组件装饰器中,我们使用hello作为组件的选择器,因此在src/app/app.component.html
文件中定义的App
组件HTML模板中,我们使用以下代码包含子组件:
<hello name=""></hello>
<p>Start editing to see some magic happen :)
</p>
After running our Angular application the hello component is rendered and becomes part of the DOM so we can query it just like any normal DOM element.
运行Angular应用程序后,hello组件将被渲染并成为DOM的一部分,因此我们可以像查询任何普通DOM元素一样查询它。
Angular中的ViewChild是什么? (What's ViewChild in Angular?)
ViewChild is a decorator that creates a view or DOM query. According to the docs
ViewChild是创建视图或DOM查询的装饰器。 根据文档
A property decorator that configures a view query. The change detector looks for the first element or the directive matching the selector in the view DOM. If the view DOM changes, and a new child matches the selector, the property is updated.
一个属性装饰器,用于配置视图查询。 变更检测器在视图DOM中查找与选择器匹配的第一个元素或指令。 如果视图DOM更改,并且有一个新的子项与选择器匹配,则该属性将更新。
The decorator takes the following meta information:
装饰器采用以下元信息:
selector
- the selector of the element to query. This can be a directive type or a name.selector
-要查询的元素的选择器。 这可以是指令类型或名称。read
- read a different token from the queried elements.read
-从查询元件读取的不同的令牌。static
- This is new in Angular 8 and indicates whether or not to resolve query results before change detection runs.static
-这是Angular 8中的新增功能,它指示是否在运行更改检测之前解析查询结果。
ViewChild
can take the following selectors:
ViewChild
可以采用以下选择器:
Classes with the
@Component
or@Directive
decorators i.e components and directives,具有
@Component
或@Directive
装饰器的类,即组件和指令,- Template reference variables, 模板参考变量
- Providers, 提供者,
TemplateRef
TemplateRef
Now, let's go back to our src/app/app.component.ts
file and let's see how we can query the child component using ViewChild
. First, change the code accordingly:
现在,让我们回到src/app/app.component.ts
文件,看看如何使用ViewChild
查询子组件。 首先,相应地更改代码:
import { Component, ViewChild, AfterViewInit } from '@angular/core';import { HelloComponent } from './hello.component';@Component({selector: 'my-app',templateUrl: './app.component.html',styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit {name = 'Angular';@ViewChild(HelloComponent, {static: false}) hello: HelloComponent;ngAfterViewInit() {console.log('Hello ', this.hello.name); }
}
In the console, you should get Hello Angular:
在控制台中,您应该得到Hello Angular :
Now, let's explain the code.
现在,让我们解释一下代码。
First, we imported HelloComponent
and ViewChild
and AfterViewInit
from the @angular/core
package:
首先,我们从@angular/core
包中导入了HelloComponent
和ViewChild
和AfterViewInit
:
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { HelloComponent } from './hello.component';
Next, we create a query called hello
that takes HelloComponent
as the selector and has static equals to false:
接下来,我们创建一个名为hello
的查询,该查询将HelloComponent
作为选择器,并且静态等于false:
@ViewChild(HelloComponent, {static: false}) hello: HelloComponent;
In Angular 8, timing for ContentChild
and ViewChild
needs to be specified explicitly.
在Angular 8中,需要明确指定ContentChild
和ViewChild
计时。
See: Why do I have to specify {static: false}
? Isn't that the default?
请参阅: 为什么我必须指定{static: false}
? 这不是默认值吗?
Next, in the ngAfterViewInit()
life-cycle hook, we can use the query to access the DOM element for the hello component. In our example, we accessed the name property of the component, after it's mounted in the DOM, which contains the Angular string:
接下来,在ngAfterViewInit()
生命周期挂钩中,我们可以使用查询访问hello组件的DOM元素。 在我们的示例中,在将组件装入包含Angular字符串的DOM中之后,我们访问了该组件的name属性:
ngAfterViewInit() {console.log('Hello ', this.hello.name); }
We can access any properties and even methods from the queried component.
我们可以从查询的组件访问任何属性甚至方法。
Note: View queries are set before the ngAfterViewInit
callback is called.
注意 :视图查询是在调用ngAfterViewInit
回调之前设置的。
使用模板引用查询标准HTML元素 (Querying Standard HTML Elements with Template References)
We can also query standard HTML elements using ViewChild
and template reference variables. Let's go back to our src/app/app.component.html
file and change it as follows:
我们还可以使用ViewChild
和模板引用变量来查询标准HTML元素。 让我们回到src/app/app.component.html
文件并按如下所示进行更改:
<hello name=""></hello><p #pRef>Start editing to see some magic happen :)
</p>
We simply added the helloRef
template reference to our hello component. Now let's change our code to access the component using its reference. Go back to the src/app/app.component.ts
file and change accordingly:
我们只是将helloRef
模板引用添加到了hello组件中。 现在,让我们更改代码以使用其引用访问组件。 返回src/app/app.component.ts
文件并进行相应更改:
import { Component, ViewChild, AfterViewInit, ElementRef } from '@angular/core';import { HelloComponent } from './hello.component';@Component({selector: 'my-app',templateUrl: './app.component.html',styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit {name = 'Angular';@ViewChild(HelloComponent, {static: false}) hello: HelloComponent;@ViewChild('pRef', {static: false}) pRef: ElementRef;ngAfterViewInit() {console.log(this.pRef.nativeElement.innerHTML); this.pRef.nativeElement.innerHTML = "DOM updated successfully!!!"; }
}
We import ElementRef
and we create a query configuration to access the <p>
DOM element with the #pRef
template reference as follows:
我们导入ElementRef
并创建查询配置,以使用#pRef
模板引用访问<p>
DOM元素,如下所示:
@ViewChild('pRef', {static: false}) pRef: ElementRef;
Next, in the ngAfterViewInit()
method we can access and modify the native DOM element using the nativeElement
object of ElementRef
:
接着,在ngAfterViewInit()
方法我们可以访问和使用该修改的源DOM元件nativeElement
的对象ElementRef
:
@ViewChild('pRef', {static: false}) pRef: ElementRef;ngAfterViewInit() {console.log(this.pRef.nativeElement.innerHTML);this.pRef.nativeElement.innerHTML = "DOM updated successfully!!!"; }
This is the live example from this link.
这是此链接中的实时示例。
Angular中的ViewChildren是什么? (What's ViewChildren in Angular?)
ViewChildren
is another property decorator which is used to query the DOM for multiple elements and return a QueryList.
ViewChildren
是另一个属性装饰器,用于在DOM中查询多个元素并返回QueryList 。
According to the docs:
根据文档 :
You can use ViewChildren to get the QueryList of elements or directives from the view DOM. Any time a child element is added, removed, or moved, the query list will be updated, and the changes observable of the query list will emit a new value.
您可以使用ViewChildren从视图DOM获取元素或指令的QueryList。 每当添加,删除或移动子元素时,查询列表都将更新,并且查询列表的可观察到的更改将发出新值。
Let's see an example.
让我们来看一个例子。
Go to the src/app/app.component.html
file and update it as follows:
转到src/app/app.component.html
文件并按如下所示进行更新:
<hello name="Angular 6" ></hello>
<hello name="Angular 7" ></hello>
<hello name="Angular 8" ></hello>
We are simply diplsaying the hello component three times. Let's now query the DOM. Open the src/app/app.component.ts
file and change it as follows:
我们只是简单地三次打招呼成分。 现在让我们查询DOM。 打开src/app/app.component.ts
文件,并进行如下更改:
import { Component, ViewChildren, AfterViewInit, QueryList } from '@angular/core';import { HelloComponent } from './hello.component';@Component({selector: 'my-app',templateUrl: './app.component.html',styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit {name = 'Angular';@ViewChildren(HelloComponent) hellos: QueryList<any>;ngAfterViewInit() {this.hellos.forEach(hello => console.log(hello));}
}
You should this output in the console:
您应该在控制台中显示以下输出:
Now, let's explain the code.
现在,让我们解释一下代码。
First we import ViewChildren
, AfterViewInit
and QueryList
from @angular/core
package.
首先,我们从@angular/core
包中导入ViewChildren
, AfterViewInit
和QueryList
。
Next, we create a query configuration for accessing multiple DOM elements:
接下来,我们创建一个用于访问多个DOM元素的查询配置:
@ViewChildren(HelloComponent) hellos: QueryList<any>;
@ViewChildren
returns a QueryList
which stores a list of items. When the state changes Angular will automatically update this query list.
@ViewChildren
返回一个QueryList
,其中存储项目列表。 当状态更改时,Angular将自动更新此查询列表。
Finally, in the ngAfterViewInit()
method, we can iterate over the query list and log each DOM element:
最后,在ngAfterViewInit()
方法中,我们可以遍历查询列表并记录每个DOM元素:
ngAfterViewInit() {this.hellos.forEach(hello => console.log(hello));}
You can find the live example from this link.
您可以从此链接中找到实时示例。
结论 (Conclusions)
In this tutorial, we've seen how we can access and modify the DOM in Angular 8 using ViewChild
and ViewChildren
decorators and a couple of other APIs like QueryList
and ngAfterViewInit()
在本教程中,我们看到了如何使用ViewChild
和ViewChildren
装饰器以及几个其他API(例如QueryList
和ngAfterViewInit()
访问和修改Angular 8中的DOM。
This post was originally posted in techiediaries.
该帖子最初发布在techiediaries中 。
翻译自: https://www.freecodecamp.org/news/angular-8-dom-queries-viewchild-and-viewchildren-example/
angular dom