我查看了Angular Materialize的代码,它似乎是一种使用jQuery和其他解决方法的Angular“shim”,以使CSS/JS框架在Angular 2中正常工作。这使得像您想要的东西有点棘手,如果它是纯Angular 2,那么就会更容易。
“Angular方式”是将每个菜单项作为单独的组件来跟踪其自身状态。它将跟踪其展开或折叠的状态,甚至可以基于该状态输出事件,这将使更改图标变得微不足道。它甚至可以跟踪被点击的次数,并随着点击次数的增加而缓慢改变颜色。当所有内容都封装在自己的组件中时,这样的东西真的很容易实现。
由于这个问题,你将不得不手动管理菜单状态,使用类似布尔数组的东西。问题在于,你将有两个不同的视图状态在不同的地方管理相同的事情 - 它们可能不总是同步的。一个在你的图标组件中,另一个在...那个materialize代码来自的地方... materialize代码可能使用CSS :active选择器在单击时更改某些内容,而你可能会在Angular中使用(click)处理程序在单击时更改某些内容,这两个东西不总是保证同步,因为有许多原因。所以如果它们失去同步,图标将会倒置,很难修复。
实际上,这可能是一种情况,其中从Angular内部使用jQuery实际上更容易,因为你正在使用的技术也使用jQuery。
但是,如果你真的想在Angular中使用这个框架使其工作,这里是如何做到的,只是要提前警告它将非常脆弱。
我会在你的组件中创建一个对象数组,表示菜单。每个对象可以保存其菜单文本、展开文本和表示其展开/折叠状态的布尔值。
你可以在组件外部定义一个接口,以便在需要时进行类型检查。
import { Component } from '@angular/core'
export interface CollapsibleItem {
label: string;
text: string;
state: boolean;
}
@Component({
selector:'whateveryouwant',
template: `
<ul class="collapsible" data-collapsible="accordion">
<li *ngFor="let item of menuItems; let i = index" (click)="menuClick(i)">
<div class="collapsible-header">
<i class="material-icons" *ngIf="item.state"> minus-icon </i>
<i class="material-icons" *ngIf="!item.state"> plus-icon </i>
{{ item.label }}
</div>
<div class="collapsible-body">
<span> {{ item.text }} </span>
</div>
</li>
`,
styles: ['']
})
export class YourComponentName {
constructor() { }
menuItems: CollapsibleItem[] = [
{ label: 'First', text: 'Lorem Ipsum', state: false },
{ label: 'Second', text: 'Lorem Ipsum', state: false },
{ label: 'Third', text: 'Lorem Ipsum', state: false },
];
menuClick(clickedItem: number) {
this.menuItems[clickedItem].state = !this.menuItems[clickedItem].state
for (let item of this.menuItems) {
if ( item !== this.menuItems[clickedItem] ) {
item.state = false;
}
}
}
}
看起来...当你在Angular中让它工作的时候,你可能已经可以构建自己的菜单项组件了,这样更容易处理并且更具可扩展性 :) 你正在创建一个包含多个属性的对象数组,并尝试通过每次点击来管理它们。这就是为什么组件被创建的原因!你可以为每个项目创建一个简单的包装器组件,但我不确定它会如何工作,因为materialize使用jQuery和CSS来选择东西。使用普通组件视图封装可能会不可预测。
与使用ngIf切换图标的替代方法是绑定innerText属性,并根据状态切换文本。
<i class="material-icons" [innerText]="item.state ? 'plus-icon' : 'minus-icon'"></i>
但我不确定materialize框架是否会快速或完全地捕捉到innerText的更改。如果您尝试混合这些技术,最好同时呈现并在它们之间切换。
此外,我不知道“plus-icon”或“minus-icon”是否是您引用这些图标的方式,但您可能明白我的意思:p