2016-11-22 4 views
0

現在、私はボタンをクリックすることで閉じることができるメニューを持っているAngular 2プロジェクトに取り組んでいます。これはまったく重すぎないので、(メニューのコンポーネントを使わずに)Angularの外に置いてみたいと思います。DOM操作用のカスタムスクリプトを作成する

しかし、実際には私は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は、サービスとの何かに移動し、私はまだ問題が発生しています。私はにconsole.logで値をデバッグする場合

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> 

アクションが正しく、トリガされ、クラス名は正しくありますが、クラスの値は変更されませんでした。私はバインディングが自動であると思った。そして、私はまだそれを変更する方法を本当に理解していません。 AMagyarのようにEmmitを使用する必要がありますか?

+0

コンポーネントのクラスを変更するには、menuserviceオブジェクトを使用します。[class] = "_ menuService.sidebarClass" – AMagyar

+0

テンプレートでプライベート値( '_menuService')を使用すると、AOTコンパイルエラーが発生します。あなたのアプリケーションをプリコンパイルしたい場合、未来のために何かを覚えておいてください – PierreDuc

+0

もちろん、私は彼がそれを変更すると確信していました – AMagyar

答えて

3

独自の実装よりもangular2を使用する利点は、プレーンJavaSccriptを使用することによるパフォーマンス上のメリットよりも大幅に優れています。私はこの道には行かないことをお勧めします。

しかし、これを続行したい場合は、関数をエクスポートして、AppComponentngAfterViewInitの内部でこの関数をインポートして呼び出す必要があります。エクスポートされた関数は、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; 
    } 

} 

次に、あなたのメニューコンポーネントには、このサービスを注入することができますし、MenuService.menuOpenにクラスopen/closedminimized/extendedをバインドします。他の構成要素については

@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){} 

} 

あなたは、メニューが開いているか、あなたはmenuServiceから値を取得するためにゲッターを使用する必要が

更新#2

を閉じたかどうかを確認するために同じロジックを使用することができます。

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(); 
    } 
} 

FYI、それは文字列クラス名の代わりに[class.open]を使用するより良い練習があります:結合唯一の方法があります。あなたがそれを好きにしたいのであれば、あなたの現在のCSSでは最小限の変更しか必要としません。

+0

角度成分を使わないのが主な理由は、私の操作はすべてのウェブサイト「メニュー」コンポーネントだけではありません。 アクションは、メニュー(メニューコンポーネントにある)とメインコンテンツ(コンポーネントの外にあります)のクラスを変更します。私はそれを行う方法がわかりません、そして、これが最善の方法であると確信していません...サービス価値を直接結びつけることによって... – Sakuto

+0

私は私の答えを更新しました。しかし、一番下の行が最初の行です。コンポーネント間で通信したい場合。おそらくあなたはサービスを必要とするでしょう – PierreDuc

+0

彼は私のソリューションで言ったようにメニューは '主要なコンテンツ'の角度コンポーネントを変更する必要があると言ったMenuコンポーネントは、メインのコンテンツの子でなければなりませんまたはサービスを介して親と通信する – AMagyar

1

私は角度成分を使用しないようにしたい理由の主な理由は、私の操作はすべてのウェブサイトではなく だけで「メニュー」コンポーネントを介して行われるべきであること 事実です。

角度2で多くのコンポーネントを作成できますが、これは簡単で実用的です。

アクションは、私のメニュー(私のメニュー コンポーネントにあります)と私のメインコンテンツ(コンポーネントの外にあります)にあるクラスを変更します。 ...多分直接のサービス価値を結合することによって...私はどのように行うのか分からない、と私はこれが最善の 方法であることはよく分からない -

主なコンテンツが持つことができます子、それはメニューそのものです。

Take a look in this link。多くの解決策があります。その1つは、子の変更を親に「放出」することです。

例が必要な場合は、すぐに提供することができます。

+0

他の回答コメントにも書いてあるとおり、私はまだこれのためにコンポーネントを作成するのが適切かどうか疑問に思っています。 – Sakuto

+0

あなたはそれをする義務はありませんが、すでにそれを使用しているので、何の努力もしていません。あなたが角度でそれを使用する場合は、より簡潔なアプリを作成するためのビルドの利点を得ることができます。また、ドキュメント全体ではなく、DOMハンドリングをコンポーネント自体に分離します。 – AMagyar

+0

OPを別の質問で編集しました。 – Sakuto