2017-12-25 37 views
1

Material 2를 사용하여 테이블 구동 식 계단식 메뉴를 구현하려고 시도했지만 변수를 사용하여 [matMenuTriggerFor]에 매트 메뉴 요소 이름 값을 할당하려고하면 런타임 오류가 발생합니다. 내가 찾은 모든 예제는 mat-menu 요소 이름을 지정하기 위해 텍스트 문자열을 사용합니다. 나는 [matMenuTriggerFor]에 바인딩이 작동하지 않았지만 닫혔다는 버그로 github보고에서 한 달 오래된 게시물을 찾았음에도 불구하고 누구나 비슷한 문제를 겪고 있음을 나타내는 웹상의 게시물을 찾을 수 없었습니다. 재질 버전 4.xx 관련 문제로. [matMenuTriggerFor]가 표현식의 값을 기대하지만 내 시도가 작동하지 않는 것으로 보입니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?변수를 사용하여 매트 메뉴 요소를 [matMenuTriggerFor]로 지정 하시겠습니까?

나는 승리 10 일 오전 브라우저는 파이어 폭스 57.0.2

내 각도 버전입니다 :

Angular CLI: 1.5.0 
Node: 6.11.3 
OS: win32 x64 
Angular: 5.1.2 
... animations, common, compiler, compiler-cli, core, forms 
... http, language-service, platform-browser 
... platform-browser-dynamic, router 

@angular/cdk: 5.0.2 
@angular/cli: 1.5.0 
@angular/material: 5.0.2 
@angular-devkit/build-optimizer: 0.0.36 
@angular-devkit/core: 0.0.22 
@angular-devkit/schematics: 0.0.42 
@ngtools/json-schema: 1.1.0 
@ngtools/webpack: 1.8.0 
@schematics/angular: 0.1.11 
@schematics/schematics: 0.0.11 
typescript: 2.4.2 
webpack: 3.8.1 

내 app.module.ts :

import { BrowserModule }   from '@angular/platform-browser'; 
import { NgModule }     from '@angular/core'; 
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 
import { MatMenuModule }   from '@angular/material/menu'; 
import { MatToolbarModule }   from '@angular/material/toolbar'; 
import { MatIconModule }   from '@angular/material/icon'; 
import { MatListModule }   from '@angular/material/list'; 


import { AppComponent }    from './app.component'; 
import { NestedMenusComponent }  from './nested-menus/nested-menus.component'; 

@NgModule({ 
    declarations: [ 
    AppComponent, 
    NestedMenusComponent 
    ], 
    imports: [ 
    BrowserModule, 
    BrowserAnimationsModule, 
    MatMenuModule, 
    MatToolbarModule, 
    MatIconModule, 
    MatListModule, 
    ], 
    providers: [], 
    bootstrap: [AppComponent] 
}) 
export class AppModule { } 

내 component.ts :

import { Component, OnInit } from '@angular/core'; 

@Component({ 
    selector: 'app-nested-menus', 
    templateUrl: './nested-menus.component.html', 
    styleUrls: ['./nested-menus.component.scss'] 
}) 
export class NestedMenusComponent implements OnInit { 

    constructor() { } 

    ngOnInit() { } 

    selected :string; 
    menuItems = [ 
    {text: "Tabledriven.Item1" }, 
    {text: "Tabledriven.Item2", templateName: "submenu"}, 
    ]; 

    select(pText :string) 
    { 
    this.selected = pText; 
    } 
} 

component.html :

<div> 
    <p>You selected: {{ selected }}</p> 

    <div class="demo-menu"> 
    <div class="menu-section"> 
     <p>Basic Menu</p> 
     <mat-toolbar> 
     <button mat-icon-button [matMenuTriggerFor]="basic"> 
      <mat-icon>more_vert</mat-icon> 
     </button> 
     </mat-toolbar> 

     <mat-menu #basic="matMenu"> 
     <button mat-menu-item (click)="select('Basic.Item1')">Basic.Item1</button> 
     <button mat-menu-item [matMenuTriggerFor]="submenu">Basic.Item2</button> 
     </mat-menu> 
    </div> 

    <div class="menu-section"> 
     <p>Table-driven Menu</p> 
     <mat-toolbar> 
     <button mat-icon-button [matMenuTriggerFor]="tabledriven"> 
      <mat-icon>more_vert</mat-icon> 
     </button> 
     </mat-toolbar> 

     <mat-menu #tabledriven="matMenu"> 
     <ng-container *ngFor="let item of menuItems"> 
      <button *ngIf=!item.templateName mat-menu-item (click)="select(item.text)">{{ item.text }}</button> 
      <button *ngIf=item.templateName mat-menu-item [matMenuTriggerFor]=item.templateName>{{ item.text }}</button> 
     </ng-container> 
     </mat-menu> 
    </div> 

    <mat-menu #submenu="matMenu"> 
     <button mat-menu-item (click)="select('Submenu.Item1')">Submenu.Item1</button> 
     <button mat-menu-item (click)="select('Submenu.Item2')">Submenu.Item2</button> 
    </mat-menu> 
    </div> 
</div> 

테이블 중심의 메뉴는 사용자 입력하기 전에 런타임 오류를 던졌습니다 : 원하는대로

ERROR 
TypeError: this.menu.close is undefined 
Stack trace: 
[email protected]:///../../../material/esm5/menu.es5.js:771:9 
[email protected]:///../../../core/esm5/core.js:12929:9 
[email protected]:///../../../core/esm5/core.js:12903:13 
[email protected]:///../../../core/esm5/core.js:12886:29 
[email protected]:///../../../core/esm5/core.js:14036:5 
[email protected]:///../../../core/esm5/core.js:14383:21 
[email protected]:///../../../core/esm5/core.js:14341:17 
[email protected]:///../../../core/esm5/core.js:14033:5 
[email protected]:///../../../core/esm5/core.js:14383:21 
[email protected]:///../../../core/esm5/core.js:14341:17 
[email protected]:///../../../core/esm5/core.js:14033:5 
[email protected]:///../../../core/esm5/core.js:14383:21 
[email protected]:///../../../core/esm5/core.js:14315:13 
[email protected]:///../../../core/esm5/core.js:14038:5 
[email protected]:///../../../core/esm5/core.js:14383:21 
[email protected]:///../../../core/esm5/core.js:14315:13 
[email protected]:///../../../core/esm5/core.js:14038:5 
[email protected]:///../../../core/esm5/core.js:15286:39 
[email protected]:///../../../core/esm5/core.js:14823:12 
[email protected]:///../../../core/esm5/core.js:11797:13 
ApplicationRef.prototype.tick/<@webpack-internal:///../../../core/esm5/core.js:6104:58 
[email protected]:///../../../core/esm5/core.js:6104:13 
[email protected]:///../../../core/esm5/core.js:6170:9 
[email protected]:///../../../core/esm5/core.js:6058:9 
PlatformRef.prototype._moduleDoBootstrap/<@webpack-internal:///../../../core/esm5/core.js:5778:74 
[email protected]:///../../../core/esm5/core.js:5778:13 
PlatformRef.prototype.bootstrapModuleFactory/</</<@webpack-internal:///../../../core/esm5/core.js:5699:21 
[email protected]:///../../../../zone.js/dist/zone.js:392:17 
[email protected]:///../../../core/esm5/core.js:4949:24 
[email protected]:///../../../../zone.js/dist/zone.js:391:17 
[email protected]:///../../../../zone.js/dist/zone.js:142:24 
scheduleResolveOrReject/<@webpack-internal:///../../../../zone.js/dist/zone.js:873:52 
[email protected]:///../../../../zone.js/dist/zone.js:425:17 
[email protected]:///../../../core/esm5/core.js:4940:24 
[email protected]:///../../../../zone.js/dist/zone.js:424:17 
[email protected]:///../../../../zone.js/dist/zone.js:192:28 
[email protected]:///../../../../zone.js/dist/zone.js:602:25 
NestedMenusComponent.html:29:10 
View_NestedMenusComponent_3 
NestedMenusComponent.html:29:10 
DebugContext_.prototype.logError 
core.js:15030 
ErrorHandler.prototype.handleError 
core.js:1488 
ApplicationRef.prototype.tick/< 
core.js:5915:54 
ZoneDelegate.prototype.invoke 
zone.js:392 
Zone.prototype.run 
zone.js:142 
NgZone.prototype.runOutsideAngular 
core.js:4701:47 
ApplicationRef.prototype.tick 
core.js:5915 
ApplicationRef.prototype._loadComponent 
core.js:5974 
ApplicationRef.prototype.bootstrap 
core.js:5862 
PlatformRef.prototype._moduleDoBootstrap/< 
core.js:5582:65 
PlatformRef.prototype._moduleDoBootstrap 
core.js:5582 
PlatformRef.prototype.bootstrapModuleFactory/</</< 
core.js:5503 
ZoneDelegate.prototype.invoke 
zone.js:392 
onInvoke 
core.js:4753 
ZoneDelegate.prototype.invoke 
zone.js:391 
Zone.prototype.run 
zone.js:142 
scheduleResolveOrReject/< 
zone.js:873 
ZoneDelegate.prototype.invokeTask 
zone.js:425 
onInvokeTask 
core.js:4744 
ZoneDelegate.prototype.invokeTask 
zone.js:424 
Zone.prototype.runTask 
zone.js:192 
drainMicroTaskQueue 
zone.js:602 
ERROR CONTEXT 
Object { view: {…}, nodeIndex: 2, nodeDef: {…}, elDef: {…}, elView: {…} } 
NestedMenusComponent.html:29:10 
Angular is running in the development mode. Call enableProdMode() to enable the production mode. 
core.js:3660 
[WDS] Disconnected! 
client:164 

기본 메뉴가 작동합니다. 표 중심의 메뉴가 열릴 때, 메뉴의 두 가지 항목이 표시되고, 두 번째 항목은 하위 메뉴 노출을 나타내는 아이콘을 포함하고 있지만 다음과 같은 런타임 오류가 발생합니다 :

ERROR 
TypeError: templateRef is undefined 
Stack trace: 
[email protected]:///../../../core/esm5/core.js:11626:30 
[email protected]:///../../../cdk/esm5/portal.es5.js:448:40 
[email protected]:///../../../cdk/esm5/portal.es5.js:303:20 
[email protected]:///../../../cdk/esm5/overlay.es5.js:647:45 
[email protected]:///../../../material/esm5/menu.es5.js:861:13 
[email protected]:///../../../material/esm5/menu.es5.js:1185:13 
View_NestedMenusComponent_3/<@ng:///AppModule/NestedMenusComponent.ngfactory.js:64:23 
[email protected]:///../../../core/esm5/core.js:13777:115 
[email protected]:///../../../core/esm5/core.js:15286:39 
[email protected]:///../../../core/esm5/core.js:14873:12 
[email protected]:///../../../core/esm5/core.js:10186:16 
renderEventHandlerClosure/<@webpack-internal:///../../../core/esm5/core.js:10807:38 
decoratePreventDefault/<@webpack-internal:///../../../platform-browser/esm5/platform-browser.js:2679:53 
[email protected]:///../../../../zone.js/dist/zone.js:425:17 
[email protected]:///../../../core/esm5/core.js:4940:24 
[email protected]:///../../../../zone.js/dist/zone.js:424:17 
[email protected]:///../../../../zone.js/dist/zone.js:192:28 
[email protected]:///../../../../zone.js/dist/zone.js:499:24 
[email protected]:///../../../../zone.js/dist/zone.js:1540:9 
[email protected]:///../../../../zone.js/dist/zone.js:1566:17 
NestedMenusComponent.html:29:10 
ERROR CONTEXT 
Object { view: {…}, nodeIndex: 0, nodeDef: {…}, elDef: {…}, elView: {…} } 
NestedMenusComponent.html:29:10 
+0

실제로 동적으로 변수를 바인드하는 것은 불가능하다고 생각합니다. 어쨌든, 당신은 또한'submenu' 변수를'matMenu'에 바인드하는 것을 잊었습니다. – Edric

+0

누락 된 바인딩을 찾을 때까지 신중하게 코드를 검사 해 주셔서 감사합니다. 첨부 된 코드를 적절하게 편집했습니다. 슬프게도, 그 수정은 결과를 변화시키지 않았다. :-(이 방법으로 묶을 수 없다는 것은 나에게 단점이있는 것 같지만 도구가 우리가 원하는 것을하지 않을 때 우리 모두는 그렇게 말하지 않느냐? –

답변

0

당신은 동적으로 수 메뉴를 빌드하십시오.
요소 이름이 아닌 요소 참조 만 있으면됩니다.

이러한 목적으로 @ViewChild@ViewChildren을 사용할 수 있습니다.

여기 코드의 working example입니다.