2016-04-08 2 views
1
> EXCEPTION: Error: Uncaught (in promise): TypeError: Cannot read 
> property 'subscribe' of undefined angular2.dev.js:23877 EXCEPTION: 
> Error: Uncaught (in promise): TypeError: Cannot read property 
> 'subscribe' of undefinedBrowserDomAdapter.logError @ 
> angular2.dev.js:23877BrowserDomAdapter.logGroup @ 
> angular2.dev.js:23888ExceptionHandler.call @ 
> angular2.dev.js:1317(anonymous function) @ 
> angular2.dev.js:12763schedulerFn @ 
> angular2.dev.js:13167SafeSubscriber.__tryOrUnsub @ 
> Rx.js:10775SafeSubscriber.next @ Rx.js:10730Subscriber._next @ 
> Rx.js:10690Subscriber.next @ Rx.js:10667Subject._finalNext @ 
> Rx.js:11191Subject._next @ Rx.js:11183Subject.next @ 
> Rx.js:11142EventEmitter.emit @ 
> angular2.dev.js:13148NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError 
> @ angular2.dev.js:13566NgZoneImpl.inner.inner.fork.onHandleError @ 
> angular2.dev.js:2128ZoneDelegate.handleError @ 
> angular2-polyfills.js:336Zone.runGuarded @ 
> angular2-polyfills.js:244drainMicroTaskQueue @ 
> angular2-polyfills.js:495ZoneTask.invoke @ angular2-polyfills.js:434 
> angular2.dev.js:23877 STACKTRACE:BrowserDomAdapter.logError @ 
> angular2.dev.js:23877ExceptionHandler.call @ 
> angular2.dev.js:1319(anonymous function) @ 
> angular2.dev.js:12763schedulerFn @ 
> angular2.dev.js:13167SafeSubscriber.__tryOrUnsub @ 
> Rx.js:10775SafeSubscriber.next @ Rx.js:10730Subscriber._next @ 
> Rx.js:10690Subscriber.next @ Rx.js:10667Subject._finalNext @ 
> Rx.js:11191Subject._next @ Rx.js:11183Subject.next @ 
> Rx.js:11142EventEmitter.emit @ 
> angular2.dev.js:13148NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError 
> @ angular2.dev.js:13566NgZoneImpl.inner.inner.fork.onHandleError @ 
> angular2.dev.js:2128ZoneDelegate.handleError @ 
> angular2-polyfills.js:336Zone.runGuarded @ 
> angular2-polyfills.js:244drainMicroTaskQueue @ 
> angular2-polyfills.js:495ZoneTask.invoke @ angular2-polyfills.js:434 
> angular2.dev.js:23877 Error: Uncaught (in promise): TypeError: Cannot 
> read property 'subscribe' of undefined 
>  at resolvePromise (angular2-polyfills.js:543) 
>  at angular2-polyfills.js:520 
>  at ZoneDelegate.invoke (angular2-polyfills.js:332) 
>  at Object.NgZoneImpl.inner.inner.fork.onInvoke (angular2.dev.js:2111) 
>  at ZoneDelegate.invoke (angular2-polyfills.js:331) 
>  at Zone.run (angular2-polyfills.js:227) 
>  at angular2-polyfills.js:576 
>  at ZoneDelegate.invokeTask (angular2-polyfills.js:365) 
>  at Object.NgZoneImpl.inner.inner.fork.onInvokeTask (angular2.dev.js:2103) 
>  at ZoneDelegate.invokeTask (angular2-polyfills.js:364)BrowserDomAdapter.logError @ 
> angular2.dev.js:23877ExceptionHandler.call @ 
> angular2.dev.js:1320(anonymous function) @ 
> angular2.dev.js:12763schedulerFn @ 
> angular2.dev.js:13167SafeSubscriber.__tryOrUnsub @ 
> Rx.js:10775SafeSubscriber.next @ Rx.js:10730Subscriber._next @ 
> Rx.js:10690Subscriber.next @ Rx.js:10667Subject._finalNext @ 
> Rx.js:11191Subject._next @ Rx.js:11183Subject.next @ 
> Rx.js:11142EventEmitter.emit @ 
> angular2.dev.js:13148NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError 
> @ angular2.dev.js:13566NgZoneImpl.inner.inner.fork.onHandleError @ 
> angular2.dev.js:2128ZoneDelegate.handleError @ 
> angular2-polyfills.js:336Zone.runGuarded @ 
> angular2-polyfills.js:244drainMicroTaskQueue @ 
> angular2-polyfills.js:495ZoneTask.invoke @ angular2-polyfills.js:434 
> angular2-polyfills.js:469 Unhandled Promise rejection: Cannot read 
> property 'subscribe' of undefined ; Zone: angular ; Task: Promise.then 
> ; Value: TypeError: Cannot read property 'subscribe' of 
> undefined(…)consoleError @ 
> angular2-polyfills.js:469drainMicroTaskQueue @ 
> angular2-polyfills.js:498ZoneTask.invoke @ angular2-polyfills.js:434 
> angular2-polyfills.js:471 Error: Uncaught (in promise): TypeError: 
> Cannot read property 'subscribe' of undefined(…)consoleError @ 
> angular2-polyfills.js:471drainMicroTaskQueue @ 
> angular2-polyfills.js:498ZoneTask.invoke @ angular2-polyfills.js:434 

dies der HTML-Code für das allgemeine Menü verwendet wird, und hier habe ich mehr Menüs ANG haben will nur den Baum mit den Menüs zu steuern Ansicht Import {Komponente, Input, Output, EventEmitter, OnInit} von 'angular2/core'; Importieren Sie {BaseMenuComponent} aus './baseMenuComponent/baseMenuComponent';Ich bin mit verschachteltem componentes ein allgemeines Menü zu erstellen, aber ich erhalte einem Fehler

<div class="menu-tree" *ngIf="menuTreeView.length>0"> 
     <div class="col-md-4" *ngFor="#menu of menuTreeView; #i = index" > 
      <base-menu 
       [menu-items-list]="menu" 
       [menu-layer]="i" 
       (select-menu-item)="selectMenuItem($event)" 
       (add-new-item)="addMenuItem($event)"> 
      </base-menu> 
     </div> 
    </div> 


@Component({ 
    selector: 'menu-component', 
    templateUrl: '/app/components/menuComponent/menuTreeComponent.html', 
    directives:[BaseMenuComponent] 
}) 

export class MenuTreeComponent implements OnInit { 
    @Input('menu-tree-data') menuDictionary; 
    //menuDictionary; 
    @Output('item-selected') selectItem:EventEmitter<Object>; 
    @Output('add-new-item') broadcastNewItem: EventEmitter<Object>; 
    ROOT_ID:number = 0; 
    ROOT_LAYER:number = 0; 

    menuTreeView:Array<Object> = new Array<Object>(); 
    //TODO implement menuService 
    constructor() { 
     this.menuDictionary = new Array<Object>(
      {id:12, layer:0, name:'asd'}, 
      {id:13, layer:0, name:'asda'}, 
      {id:14, layer:0, name:'asdd'}, 
      {id:15, layer:1, parentId:13, name:'asds'}, 
      {id:16, layer:1, parentId:13, name:'asdg'}, 
      {id:17, layer:1, parentId:13, name:'asdxz'}, 
      {id:18, layer:1, parentId:14, name:'asd1e'}, 
      {id:19, layer:2, parentId:17, name:'asd1e1'}, 
      {id:20, layer:2, parentId:17, name:'asd1e2'}, 
      {id:21, layer:2, parentId:17, name:'asd1e3'}); 
    } 

    ngOnInit(){ 
     this.selectItem = new EventEmitter<Object>(); 
     this.broadcastNewItem = new EventEmitter<Object>(); 
     this.menuDictionary = this.mapManuTree(this.menuDictionary);  
     this.menuTreeView.push(this.getRootLayer()); 
    } 

    mapManuTree(menuTree){ 
     for (let i = 0; i < menuTree.length; i++) { 
      menuTree[i].hasChildrens = this.checkIfMenuItemHasChildrens(menuTree[i], menuTree); 
     } 
    } 

    checkIfMenuItemHasChildrens(menuItem, menuTree){ 
     for (let i = 0; i < menuTree.length; i++) { 
      if(menuItem.id === menuTree[i].parentId){ 
       return true; 
      } 
     } 
     return false; 
    } 

    selectMenuItem(menuItem){ 
     if(!menuItem.hasChildrens){ 
      this.selectItem.emit(menuItem); 
      return; 
     } 
     this.menuTreeView = this.getTreeViewForMenuItem(menuItem); 
    } 

    getTreeViewForMenuItem(menuItem){ 
     let menuView = this.menuTreeView; 
     var nextLayer = menuItem.layer + 1; 

     menuView[nextLayer] = new Array<Object>(); 

     for (var i = 0; i < this.menuDictionary.length; i++) { 
      if (this.menuDictionary[i].parentId <= menuItem.id){ 
       menuView[nextLayer].push(this.menuDictionary[i]); 
      } 
     } 

     return menuView; 
    } 

    getRootLayer(){ 
     let firstLayer = new Array<Object>(); 

     for (var i = 0; i < this.menuDictionary.length; i++) {   
      if(this.menuDictionary[i].layer === this.ROOT_LAYER) 
      { 
       firstLayer.push(this.menuDictionary[i]); 
      } 
     } 

     return firstLayer 
    } 
} 

ist die generische Liste für das Basismenü

import {Component, Input, Output, EventEmitter, OnInit} from 'angular2/core'; 

@Component({ 
    selector: 'base-menu', 
    //templateUrl: '/app/components/menuComponent/baseMenuComponent/baseMenuComponent.html' 
    template:` 
    <div class="base-menu-component"> 
     <ul class="nav nav-pills nav-stacked"> 
      <li class="form-group row"> 
       <input class="form-control" [(ngModel)]="newMenuItem"> 
       <button class="btn btn-success" (click)="addMenuItem()"> 
        <span class="glyphicon glyphicon-plus"></span> 
       </button> 
       <button class="btn btn-success" (click)="clearMenuItem()"> 
        <span class="glyphicon glyphicon-remove"></span> 
       </button> 
      </li> 
      <li *ngFor="#item of menuItems" [class]="isItemSelected(item) ? 'active':''" (click)="selectItem(item)"> 
       <a>{{item.name}}</a> 
      </li> 
     </ul> 
    </div> 
    `, 
    //inputs:['menu-items-list',], 
}) 

export class BaseMenuComponent implements OnInit { 
    @Input('menu-items-list') menuItemsList:Array<MenuItem>; 
    @Input('menu-layer') menuLayer:number; 
    @Output('select-menu-item') broadcastMenuItem: EventEmitter<MenuData> = new EventEmitter<MenuData>(); 
    @Output('add-new-item') broadcastNewItem: EventEmitter<MenuData> = new EventEmitter<MenuData>(); 

    selectedItem:MenuItem; 
    newMenuItem:string; 

    constructor() { } 

    ngOnInit(){ 
     this.selectedItem = this.menuItemsList && this.menuItemsList.length > 0 ? this.menuItemsList[0] : null; 
     this.newMenuItem = ""; 
    } 

    isItemSelected(menuItem){ 
     return this.selectedItem == menuItem; 
    } 

    selectItem(menuItem){ 
     this.selectedItem = menuItem; 
     this.broadcastMenuItem.emit({menuItem:menuItem, menuLayer:this.menuLayer}); 
    } 

    addMenuItem(){ 
     this.broadcastNewItem.emit({menuItem:this.newMenuItem, menuLayer:this.menuLayer}); 
     this.clearMenuItem(); 
    } 

    clearMenuItem(){ 
     this.newMenuItem = ""; 
    } 
} 

interface MenuItem{ 
    id; 
    layer; 
    parentId; 
    name; 
} 

interface MenuData{ 
    menuItem; 
    menuLayer; 
} 
+0

Es wäre eingerichtet hilfreich, wenn Sie eine kleine Probe und plnkr oder jsfiddle laden konnten oder [codepen] (http://codepen.io/). – surfmuggle

+0

[hier ist der Plunkr Code] (https://plnr.rc/edit/90shO2pHTKxja28nv7gR) – Nicu

+0

es funktioniert nicht ich meine nicht initialisiert. – micronyks

Antwort

1

ich das denke,

ngOnInit(){ 
    this.selectItem = new EventEmitter<Object>(); 
    this.broadcastNewItem = new EventEmitter<Object>(); 

den Fehler verursacht.

Warum man sich nicht wie

@Output('item-selected') selectItem:EventEmitter<Object> = new EventEmitter<Object>(); 
@Output('add-new-item') broadcastNewItem:EventEmitter<Object> = new EventEmitter<Object>(); 

oder im Konstruktor

constructor(){ 
    this.selectItem = new EventEmitter<Object>(); 
    this.broadcastNewItem = new EventEmitter<Object>(); 
+0

Vielen Dank, können Sie erklären, warum der Emitter auf den Konstruktor initialisiert werden muss oder wenn Sie ihn deklarieren? – Nicu

+1

Angular ruft 'ngOnInit()' auf, nachdem die Bindungen aufgelöst wurden. '@Output()' dient zum Binden von Kind an Eltern. Daher versucht es, Ihre Ausgaben zu abonnieren, aber sie sind noch nicht initialisiert und wirft. –

Verwandte Themen