我目前正在开发一个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?
答案 0 :(得分:3)
在您自己的实现之上使用angular2
的优势大大超过了使用平面JavaSccript可以获得的性能边际效益。我建议不要走这条路。
如果您确实想要继续此操作,则应导出一个函数并导入并在ngAfterViewInit
的{{1}}内调用此函数。导出的函数应添加点击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
绑定到MenuService.menuOpen。
minimized/extended
对于其他组件,您可以使用相同的逻辑来查看菜单是打开还是关闭
更新#2
您必须使用getter从menuService获取值。只有一种方式绑定:
@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){}
}
仅供参考,使用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();
}
}
代替字符串类名称是一种更好的做法。如果你想这样做,那么你当前的css只需要很小的改变。
答案 1 :(得分:1)
我想避免使用Angular组件的主要原因是 事实上,我的操作应该在所有的网站上完成,而不是 只是“菜单”组件。
您可以在Angular 2中创建许多组件,它非常简单且非常实用。
该操作将更改我的菜单上的课程(位于我的菜单中 组件)和我的主要内容(位于组件外部)。 我不知道怎么做,我不确定这是最好的 方式...也许直接绑定服务价值...... -
主要内容可以包含菜单本身的子项。
Take a look in this link。有很多解决方案,其中之一就是将孩子的“发射”变为父母。
如果您需要一个例子,我可以快速提供一个。