在 Angular 中使用 getElementById 可以吗?
Posted
技术标签:
【中文标题】在 Angular 中使用 getElementById 可以吗?【英文标题】:Is it OK to use getElementById in Angular? 【发布时间】:2020-01-23 05:22:19 【问题描述】:我正在浏览 Angular 文档并看到以下代码 sn-p。在我的脑海里,我想我记得在 Angular 中使用 document.getElementById()
是不受欢迎的,甚至不鼓励使用 ElementRefs
(以帮助防止 XSS 攻击)。如果确实不鼓励这些,那么为特定元素上的事件设置 Observable 的最佳实践是什么?
来自Angular Observables Documentation
import fromEvent from 'rxjs';
import ajax from 'rxjs/ajax';
import map, filter, debounceTime, distinctUntilChanged, switchMap from 'rxjs/operators';
const searchBox = document.getElementById('search-box'); // <-- Is this OK?
const typeahead = fromEvent(searchBox, 'input').pipe(
map((e: KeyboardEvent) => e.target.value),
filter(text => text.length > 2),
debounceTime(10),
distinctUntilChanged(),
switchMap(() => ajax('/api/endpoint'))
);
【问题讨论】:
可以使用模板变量,然后使用@ViewChild('your template variable name')
访问元素。
这个答案会对你有所帮助,***.com/questions/38944725/…
以这种方式使用它的文档中的奇怪样本我猜它“没问题”,然后当样本在官方文档中时:D 我根本不会这样做。我可能会将表单控件附加到输入并收听valueChanges
。
【参考方案1】:
在 Angular 中使用手动处理 DOM 是一种糟糕的方法。在 Angular 应用程序中,您应该始终使用 Angular 的方法来呈现页面。因为在大多数情况下,您将来需要为您的应用程序提供服务器端渲染,以使其对 Google 友好。但是后端的 Angular 的 s-s-r 引擎(Angular Universal)只模拟 XHR 对象,而不模拟 DOM 方法。
【讨论】:
【参考方案2】:我建议使用 angulars ViewChild
与模板中的组件进行交互。
ViewChild - 装饰器 API
配置视图查询的属性装饰器。变化检测器 查找第一个元素或与选择器匹配的指令 视图 DOM。如果视图 DOM 发生变化,并且新的子节点匹配 选择器,属性已更新。
例如:
import Component, Directive, Input, ViewChild from '@angular/core';
@Directive(selector: 'pane')
export class Pane
@Input() id !: string;
@Component(
selector: 'example-app',
template: `
<pane id="1" *ngIf="shouldShow"></pane>
<pane id="2" *ngIf="!shouldShow"></pane>
<button (click)="toggle()">Toggle</button>
<div>Selected: selectedPane</div>
`,
)
export class ViewChildComp
@ViewChild(Pane, static: false)
set pane(v: Pane)
setTimeout(() => this.selectedPane = v.id; , 0);
selectedPane: string = '';
shouldShow = true;
toggle() this.shouldShow = !this.shouldShow;
这是Understanding ViewChildren, ContentChildren, and QueryList in Angular的一个很好的例子
【讨论】:
我错了还是不再支持!:
语法?
嗯示例来自apiangular.io/api/core/ViewChild,可能已经过时了?【参考方案3】:
使用响应式可能是更好的方法
//html:
<input #search [formControl]="search"/>
//Component
search=new FormControl('')
search.valueChanges.pipe(
filter(text => text.length > 2),
debounceTime(10),
distinctUntilChanged(),
switchMap(() => ajax('/api/endpoint'))
).subscribe();
【讨论】:
以上是关于在 Angular 中使用 getElementById 可以吗?的主要内容,如果未能解决你的问题,请参考以下文章