我目前正在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所获得的边际性能优势。我建议不要走这条路。

但是,如果确实要继续执行此操作,则应导出函数并导入并在ngAfterViewInitAppComponent中调用此函数。导出的函数应添加单击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/closedminimized/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中进行最小的更改即可。

09-16 22:10