我目前正在Angular 2项目中工作,在该项目中,我的菜单应该可以通过单击按钮关闭。由于这一点都不繁重,所以我想将其放在Angular之外(不使用菜单组件)。
但是我不确定该怎么做,实际上我只是在HTML标头中放了一个简单的javascript,但我不应该把它放到其他地方吗?
另外,代码应该是什么?使用类,导出一些东西?目前,这是我的代码:
var toggleMenuButton = document.getElementById('open-close-sidebar');
var contentHolder = document.getElementById('main-content');
var menuHolder = document.getElementById('sidebar');
var menuIsVisible = true;
var updateVisibility = function() {
contentHolder.className = menuIsVisible ? "minimised" : "extended";
menuHolder.className = menuIsVisible ? "open" : "closed";
}
toggleMenuButton.addEventListener('click', function() {
menuIsVisible = !menuIsVisible;
updateVisibility();
});
终于有了MenuComponent和服务,但我仍然遇到问题。
MenuService.ts
@Injectable()
export class MenuService {
isAvailable: boolean = true;
isOpen: boolean = true;
mainClass: string = "minimised";
sidebarClass: string = "open";
updateClassName() {
this.mainClass = this.isOpen ? "minimised" : "extended";
this.sidebarClass = this.isOpen ? "open" : "closed";
}
toggleMenu(newState: boolean = !this.isOpen) {
this.isOpen = newState;
this.updateClassName();
}
}
MenuComponent.ts
export class MenuComponent {
constructor(private _menuService: MenuService) { }
public isAvailable: boolean = this._menuService.isAvailable;
public sidebarClass: string = this._menuService.sidebarClass;
toggleMenu() {
this._menuService.toggleMenu();
}
}
MenuComponent.html
<div id="sidebar" [class]="sidebarClass" *ngIf="isAvailable">
...
<div id="open-close-sidebar"><a (click)="toggleMenu()"></a></div>
正确触发了该操作,如果我使用console.log调试值,则类名正确,但它不会更改类的值。我认为绑定是自动的。而且我仍然不太了解如何更改它。是否必须像AMagyar建议的那样使用Emmit?
最佳答案
在自己的实现之上使用angular2
的优势大大超过了使用plane JavaSccript所获得的边际性能优势。我建议不要走这条路。
但是,如果确实要继续执行此操作,则应导出函数并导入并在ngAfterViewInit
的AppComponent
中调用此函数。导出的函数应添加单击EventListener
,并(重要)设置document.getElementById
变量。因为脚本加载后可能尚无法找到那些元素。
但是,让我再次强调一下,angular2
已针对这些任务进行了优化,一旦您对其更加熟悉,编写代码也将变得更加容易。
更新
对于组件间的通信,您应该立即考虑一项服务。只需创建一个存储菜单状态的服务,然后将其添加到全局ngModule
提供程序数组中即可。例如:
export class MenuService {
public get menuOpen(): boolean {
return this._menuOpen;
}
private _menuOpen: boolean;
public openMenu() : void {
this._menuOpen = true;
}
public closeMenu() : void {
this._menuOpen = false;
}
public toggleMenu() : void {
this._menuOpen = !this._menuOpen;
}
}
然后,您可以将该服务注入到菜单组件中,并将
open/closed
和minimized/extended
类绑定到MenuService.menuOpen。@Component({
selector : 'menu'
template : `
<button (click)="menuService.toggleMenu()">click</button>
<div id="open-close-sidebar" [class.open]="menuService.menuOpen"></div>
`
})
export class MenuComponent {
constructor(public menuService: MenuService){}
}
对于其他组件,您可以使用相同的逻辑来查看菜单是打开还是关闭
更新#2
您必须使用getter来从menuService获取值。绑定只有一种方法:
export class MenuComponent {
constructor(private _menuService: MenuService) { }
public get isAvailable(): boolean {
return this._menuService.isAvailable;
}
public get sidebarClass(): string {
return this._menuService.sidebarClass;
}
toggleMenu() {
this._menuService.toggleMenu();
}
}
仅供参考,最好使用
[class.open]
代替字符串类名。如果您想那样做,则只需在当前CSS中进行最小的更改即可。