[英]Why addClass does not work for DOM element in Angular?
I have DOM component:我有 DOM 组件:
<app-ui-element-block (click)=do($event)></app-ui-element-block>
Method is:方法是:
public do($event){
const elms = document.getElementsByTagName('app-ui-element-block');
for (let i = 0; i < elms.length; i++) {
elms[i].classList.remove('active');
}
$event.target.classList.add('active');
}
Why I can not set class for selected element DOM as component?为什么我不能将选定元素 DOM 的 class 设置为组件?
Why not use a more "angular way".为什么不使用更“有角度的方式”。 You can use the ngClass directive instead.
您可以改用ngClass指令。
<app-ui-element-block [ngClass]="{'active': isActive}" (click)="isActive=true"></app-ui-element-block>
Then you just need a field in your root component named isActive
.然后你只需要在你的根组件中有一个名为
isActive
的字段。 If you have multiple items then you could either use an array or an indexer or something similar.如果您有多个项目,那么您可以使用数组或索引器或类似的东西。
So you have a component named UiElementBlock
, and you want this to have a class or not:因此,您有一个名为
UiElementBlock
的组件,并且您希望它是否具有 class :
If these are placed using an *ngFor
, you can use the looped element as indicator (or something else):如果这些是使用
*ngFor
放置的,您可以使用循环元素作为指示符(或其他东西):
<app-ui-element-block
*ngFor="let block of blocks"
[class.active]="block === active"
(click)="active = block">
</app-ui-element-block>
In your parent component you need to define this active
:在您的父组件中,您需要定义这个
active
:
export class ParentUiComponent {
active?: UiElementBlock;
blocks = [
'ui1',
'ui2',
'ui3'
];
}
If you are not using the *ngFor
, and you are manually placing these blocks, you also have the choice to manually assign a variable to it:如果您不使用
*ngFor
并且手动放置这些块,您还可以选择手动为其分配变量:
<app-ui-element-block
[class.active]="block1 === active"
(click)="active = block1"
#block1>
</app-ui-element-block>
<div> Some random content </div>
<app-ui-element-block
[class.active]="block2 === active"
(click)="active = block2"
#block2>
</app-ui-element-block>
Things get more wild if these components are spread across multiple parent components.如果这些组件分布在多个父组件中,事情会变得更加疯狂。 You would need to do this logic inside the block itself, in combination with a service:
您需要结合服务在块本身内部执行此逻辑:
export interface ActivatableBlock {
active: boolean;
}
@Injectable({
providedIn: 'root'
})
export class UiElementBlockService {
private active?: ActivatableBlock;
activate(block: ActivatableBlock): void {
if (this.active) {
this.active = false;
}
block.active = true;
this.active = block;
}
}
@Component({
selector: 'app-ui-element-block',
template: ``
})
export class UiElementBlock implements ActivatableBlock {
@HostBinding('class.active')
active?: boolean;
constructor(private ub: UiElementBlockService) {}
@HostListener('click')
onClick(): void {
this.ub.activate(this);
}
}
So, that's just a couple of ways of doing it, without using the DOM, and making things more reusable and easier to test.所以,这只是做这件事的几种方法,不使用 DOM,并使事情更可重用和更容易测试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.