为DOM操作创建自定义脚本

时间:2016-11-22 10:18:54

标签: javascript angular

我目前正在开发一个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?

2 个答案:

答案 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。有很多解决方案,其中之一就是将孩子的“发射”变为父母。

如果您需要一个例子,我可以快速提供一个。