2017-02-19 2 views
0

각도 2를 처음 사용하고 "onclick"이벤트를 부모 컴포넌트/템플릿의 #sitenav 객체에 바인딩하려고합니다.각도 2 : 정의되지 않은 'close'속성을 읽을 수 없습니다.

menu.html (아이 템플릿)

<md-list-item *ngFor="let entry of entries"> 
    <button md-menu-item (click)="sidenav.close()"> 
     <md-icon>{{entry.icon}}</md-icon> 
     <span><a routerLink="{{entry.route}}">{{entry.link}}</a></span> 
    </button> 
</md-list-item> 

menu.ts (아이 템플릿 구성 요소 파일)

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

@Component({ 
    moduleId:module.id, 
    selector: 'navlinks', 
    templateUrl: 'menubtn.component.html' 
}) 
export class MenuBtnComponent { 
    entries = []; 

@Output() buttonClicked : EventEmitter<any> = new EventEmitter(); 

    close(value:any){ 
    this.buttonClicked.emit("close"); 
    } 

    constructor() {} 

    ngOnInit() { 
    this.entries = [ 
     { 
      icon: 'home', 
      route: '/', 
      link: 'Home' 
     }, 
     { 
      icon: 'sentiment_satisfied', 
      route: '/about', 
      link: 'About Us' 
     }, 
     { 
      icon: 'content_paste', 
      route: '/work', 
      link: 'Out Work' 
     }, 
     { 
      icon: 'mail', 
      route: '/contact', 
      link: 'Get In Touch' 
     }, 
    ]; 

    } 
} 

sitenav.ts (부모 템플릿 구성 요소)

import {Component, ViewChild, ViewEncapsulation, Directive} from '@angular/core'; 
import { MdMenuModule, MdMenuTrigger} from '@angular/material'; 

import { MenuBtnComponent } from './menubtn.component'; 


@Component({ 
    moduleId:module.id, 
    encapsulation: ViewEncapsulation.Emulated, 
    selector: 'sitenav', 
    templateUrl: './sitenav.component.html', 
    styleUrls: [ './sitenav.component.css'] 
}) 
export class SitenavComponent { 
clickedButton(val){ 
    console.log(val); 
} 
} 

:

sitenav.html (부모 템플릿) 클릭시

<!--sidenav--> 
    <md-sidenav 
    #sidenav 
    class="app-sidenav md2 md-sidenav md-sidenav-side md-sidenav-closed" 
    mode="side"> 
    <md-list flex="" role="list" class="flex"> 
     <navlinks (buttonClicked)="close($event)"></navlinks> 
    </md-list> 
    </md-sidenav> 
<!--//sidenav--> 

(click)="sidenav.close()" 가까운 #sitenav 그러나 그렇게 나는 오류가 발생하고있는 menu.html 템플릿에서 볼 수 있도록하지 않는 것

Cannot read property 'close' of undefined 

#sidenav에 어떻게 표시합니까?

답변

1

자식에서 부모 구성 요소 메서드에 직접 액세스 할 수 없습니다. Output() 매개 변수는 요구 사항을 달성하는 가장 좋은 방법입니다.

당신의 코드가 있어야한다

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

@Component({ 
    moduleId:module.id, 
    selector: 'navlinks', 
    templateUrl: 'menubtn.component.html' 
}) 
export class MenuBtnComponent { 
    @Output() buttonClicked : EventEmitter<string> = new EventEmitter<string>(); 
    entries = []; 

    constructor() {} 

    ngOnInit() { 
     .... 

    } 
    close(value:any){ 
    this.buttonClicked.emit("close"); 
    } 
} 

귀하의 HTML 마크 업으로 수정되어야한다

<md-list-item *ngFor="let entry of entries"> 
     <button md-menu-item (buttonClicked)="close($event)"> 
     <md-icon>{{entry.icon}}</md-icon> 
     <span><a routerLink="{{entry.route}}">{{entry.link}}</a></span> 
    </button> 
</md-list-item> 

<md-list-item *ngFor="let entry of entries"> 
     <button md-menu-item (buttonClicked)="close($event)"> 
      <md-icon>{{entry.icon}}</md-icon> 
      <span><a routerLink="{{entry.route}}">{{entry.link}}</a></span> 
     </button> 
</md-list-item> 

부모 구성 요소 TS 파일을 가지고 있어야로

당신의 부모 구성 요소가 있어야한다 아래 방법

clickedButton(val){ 
    console.log(val); 
} 

참고 : 사용자가 close() 메소드에 액세스하는 방법은 대소 문자에도 유효합니다. ChildCom 메서드 ParentComponent #sideNav가 자식 구성 요소와 관련이 없으며 close() 메서드에 액세스 할 수 있다는 것은 꽤 분명합니다. 이 일을

+0

HTML 마크 업과 상위 구성 요소가 코드에서 동일합니까? – HGB

+0

위의 코드를 업데이트했지만 아무 일도 일어나지 않습니다. 오류 없음. ' HGB

+0

그리고 #sidenav 요소를 닫으려는 것이 무엇입니까? – HGB

0

또 다른 가능한 방법은 이벤트 버스 서비스에 의해

eventbusservice.ts

import { Subject } from 'rxjs/Rx'; 
import { Observable } from 'rxjs/Observable'; 

export class EventBusService 
{ 
    bus:Subject<Event> = new Subject<Event>(); 

    dispatch(data:Event){ 
     this.bus.next(data); 
    } 

    listen(type:string):Observable<Event> { 
     return this.bus.filter(event=>event.type === type); 
    } 
} 

menu.ts

import { Component, Output, EventEmitter } from '@angular/core'; 
    import { EventBusService } from './eventbusservice' 
@Component({ 
    moduleId:module.id, 
    selector: 'navlinks', 
    templateUrl: 'menubtn.component.html' 
}) 
export class MenuBtnComponent { 
    entries = []; 

    constructor(private eventbus:EventBusService) {} 

    ngOnInit() { 
     .... 

    } 
    close(){ 
    this.eventbus.dispatch("close"); 
    } 
} 

sitenav입니다.TS

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

@Component({ 
    moduleId: module.id, 
    selector: 'site-nav', 
    templateUrl: 'sitenav.html' 
}) 
export class SiteNavComponent implements OnInit { 
    constructor(private eventbus:EventBusService) { 
this.eventbus.listen("close").subscribe((e)=>{this.closeSomething()}) 

    } 
closeSomething(){ 

} 
    ngOnInit() { } 
} 

menu.html

<md-list-item *ngFor="let entry of entries"> 
    <button md-menu-item (click)="close()"> 
     <md-icon>{{entry.icon}}</md-icon> 
     <span><a routerLink="{{entry.route}}">{{entry.link}}</a></span> 
    </button> 
</md-list-item> 

하나 개의 구성 요소의 변화가 많은 다른 구성 요소에 미치는 영향 (단지 부모없는 구성 요소)이있는 경우이 과정이 도움이됩니다.

+0

흥미 롭습니다. 버스 서비스를 사용하지 않는 이유가 있습니까? 방금 앵귤러 2로 시작했고 가능한 표준에 가깝게 지키고 싶다면 모든 구성 요소에서 이벤트를 수신 할 때마다 eventbusservice.ts를 가져올 수 있습니까? – HGB

+0

https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service –

+0

감사합니다. Sai,하지만 EventEmitter 옵션을 사용하여 위의 방법으로 무엇이 잘못되었는지 말할 수 있습니까? – HGB

관련 문제