Angular文档提供了一个创建属性指令的示例,该指令可以更改元素的背景颜色:
https://angular.io/docs/ts/latest/guide/attribute-directives.html
<p myHighlight>Highlight me!</p>
import { Directive, ElementRef } from '@angular/core';
@Directive({ selector: '[myHighlight]' })
export class HighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
}
我还可以使用el.nativeElement
获取元素的内容(例如Highlight me!
),修改此内容并更新元素吗?
答案 0 :(得分:24)
实际上,我应该做console.log(el.nativeElement)
的评论应该指向正确的方向,但我没想到输出只是一个代表DOM Element
的字符串。
要以帮助解决问题的方式检查它,您需要做的就是在示例中执行console.log(el)
,然后您就可以访问nativeElement
对象了查看名为innerHTML
的属性。
这将导致原始问题的答案:
let myCurrentContent:string = el.nativeElement.innerHTML; // get the content of your element
el.nativeElement.innerHTML = 'my new content'; // set content of your element
由于这是公认的答案,网络工作者日常变得越来越重要(无论如何这被认为是最佳实践)我想在这里添加Mark Rajcok的这个建议。
以编程方式操作DOM Elements
的最佳方法是使用Renderer:
constructor(private _elemRef: ElementRef, private _renderer: Renderer) {
this._renderer.setElementProperty(this._elemRef.nativeElement, 'innerHTML', 'my new content');
}
由于现在不推荐使用Renderer
,请使用Renderer2代替setProperty
This question with its answer解释了console.log
行为。
这意味着,对于这种情况, console.dir(el.nativeElement)
将是您在控制台中作为“可检查”对象访问DOM Element
的更直接方式。
希望这会有所帮助。
答案 1 :(得分:10)
我建议使用Render,因为ElementRef API doc建议:
...看看Renderer,它提供了可以安全使用的API,即使不支持直接访问本机元素也是如此。 依靠直接DOM访问会在您的应用程序和渲染层之间创建紧密耦合,这将使得无法将您的应用程序分离并将您的应用程序部署到Web worker或Universal 。
始终使用渲染器,因为它会使您在使用Universal或WebWorkers时能够使用代码(或您正确的库)。
import { Directive, ElementRef, HostListener, Input, Renderer } from '@angular/core';
export class HighlightDirective {
constructor(el: ElementRef, renderer: Renderer) {
renderer.setElementProperty(el.nativeElement, 'innerHTML', 'some new value');
}
}
看起来Render有一个getElementProperty()方法,所以我想我们仍然需要为那部分使用NativeElement。或者(更好)将内容作为输入属性传递给指令。
答案 2 :(得分:5)
这是因为
的内容var array1 = [{ address: "www.example.com", hits: 1 }, { address: "www.anotherone.org", hits: 10 }],
array2 = [{ address: "www.example.com", buttons: 1 }, { address: "www.yetanotherone.info", buttons: 2 }],
array3 = [{ address: "www.example.com", cons: 1 }, { address: "andevenonemore.com", cons: 1 }],
grouped = [];
[].concat(array1, array2, array3).forEach(function (a) {
if (!this[a.address]) {
this[a.address] = { address: a.address, hits: 0, buttons: 0, cons: 0 };
grouped.push(this[a.address]);
}
Object.keys(a).forEach(function (k) {
if (k !== 'address') {
this[a.address][k] += a[k];
}
}, this);
}, Object.create(null));
console.log(grouped);
调用HighlightDirective的构造函数时,尚未呈现,因此尚无内容。
如果您实施AfterContentInit挂钩,您将获得该元素及其内容。
<p myHighlight>Highlight me!</p>
答案 3 :(得分:0)
基于@Mark答案,我将构造函数添加到指令中,并且可以与我一起使用。
我分享了一个值得关注的样本。
constructor(private el: ElementRef, private renderer: Renderer) {
}
TS文件
@Directive({ selector: '[accordion]' })
export class AccordionDirective {
constructor(private el: ElementRef, private renderer: Renderer) {
}
@HostListener('click', ['$event']) onClick($event) {
console.info($event);
this.el.nativeElement.classList.toggle('is-open');
var content = this.el.nativeElement.nextElementSibling;
if (content.style.maxHeight) {
// accordion is currently open, so close it
content.style.maxHeight = null;
} else {
// accordion is currently closed, so open it
content.style.maxHeight = content.scrollHeight + "px";
}
}
}
HTML
<button accordion class="accordion">Accordian #1</button>
<div class="accordion-content">
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quas deleniti molestias necessitatibus quaerat quos incidunt! Quas officiis repellat dolore omnis nihil quo,
ratione cupiditate! Sed, deleniti, recusandae! Animi, sapiente, nostrum?
</p>
</div>
演示https://stackblitz.com/edit/angular-directive-accordion?file=src/app/app.component.ts