2016-08-23 48 views
5

我有这个组件叫做multiselect.component,我在.ts文件中访问它的一个html元素(<select id="category-select">)Angular 2 viewchild不工作 - 无法读取属性nativeElement undefined

multiselect.component.html:

<select id="category-select" multiple class="form-control"> 
    <option value="1">Meat</option> 
    <option value="2">Dairy</option> 
    <option value="3">Confectionary</option> 
    <option value="4">Dessert</option> 
    <option value="7">Baking</option> 
    <option value="6">Grocers</option> 
    <option value="5">Restaurants</option> 
    <option value="8">Condiments</option> 
    <option value="9">beverages</option> 
</select> 
<div class="form-control-icon" id="keywords-icon"></div> 

multiselect.component.ts:

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

@Component({ 
    selector: 'multiselect', 
    templateUrl: 'app/shared/multiselect.component.html', 
    styleUrls: [ 'app/shared/multiselect.component.css' ] 
}) 
export class MultiselectComponent implements OnInit { 
    items = 'one two three'.split(' '); 
    selectedCategories; 
    allSelected; 
    numberOfCategories = 9; 

    ngOnInit() { 
     this.selectedCategories = []; 
     (<any>$("#category-select")).multiselect({ 
      buttonWidth: '100%', 
      buttonContainer: '<div style="height: 34px;" />', 
      buttonClass: 'none', 
      nonSelectedText: "select categories", 
      nSelectedText: ' categories', 
      allSelectedText: "all categories", 
      selectAllNumber: false, 
      includeSelectAllOption: true, 
      disableIfEmpty: true, 
      onSelectAll:() => { 
       this.allSelected = true; 
      }, 
      onInitialized:() => { 

      }, 
      onChange: (option, checked) => { 
       this.changed(); 
      } 
     }); 
    } 

    changed() { 
     this.selectedCategories = []; 
     var self = this; 

     $('#category-select option:selected').each(function() { 
      self.selectedCategories.push(
       <any>($(this).text(), $(this).val()) 
      ) 
     }); 
     console.log(this.selectedCategories); 
     if (this.selectedCategories.length < this.numberOfCategories) { 
      this.allSelected = false; 
     } 
    } 
} 

我认为我访问它的方式是不好的做法,通过使用jQuery。我认为它可以通过@viewChild来访问。

所以我想改变它像这样(我最初只是摆脱第一的jQuery元素访问后来将做休息):

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

@Component({ 
    selector: 'multiselect', 
    templateUrl: 'app/shared/multiselect.component.html', 
    styleUrls: [ 'app/shared/multiselect.component.css' ] 
}) 
export class MultiselectComponent implements OnInit { 
    items = 'one two three'.split(' '); 
    selectedCategories; 
    allSelected; 
    numberOfCategories = 9; 

    @ViewChild('category-select') select; 

    ngOnInit() { 
     this.selectedCategories = []; 
     this.select.nativeElement.multiselect({ 
      buttonWidth: '100%', 
      buttonContainer: '<div style="height: 34px;" />', 
      buttonClass: 'none', 
      nonSelectedText: "select categories", 
      nSelectedText: ' categories', 
      allSelectedText: "all categories", 
      selectAllNumber: false, 
      includeSelectAllOption: true, 
      disableIfEmpty: true, 
      onSelectAll:() => { 
       this.allSelected = true; 
      }, 
      onInitialized:() => { 

      }, 
      onChange: (option, checked) => { 
       this.changed(); 
      } 
     }); 
    } 

    changed() { 
     this.selectedCategories = []; 
     var self = this; 

     $('#category-select option:selected').each(function() { 
      self.selectedCategories.push(
       <any>($(this).text(), $(this).val()) 
      ) 
     }); 
     console.log(this.selectedCategories); 
     if (this.selectedCategories.length < this.numberOfCategories) { 
      this.allSelected = false; 
     } 
    } 
} 

我得到这个控制台错误:

> EXCEPTION: Error: Uncaught (in promise): EXCEPTION: Error in app/find-page/find-form.component.html:0:56 
ORIGINAL EXCEPTION: TypeError: Cannot read property 'nativeElement' of undefined 
ORIGINAL STACKTRACE: 
TypeError: Cannot read property 'nativeElement' of undefined 
    at MultiselectComponent.System.register.context_1.execute.MultiselectComponent.ngOnInit (http://localhost:3000/js/app/shared/Multiselect.component.js:29:32) 
    at DebugAppView._View_FindFormComponent0.detectChangesInternal (FindFormComponent.ngfactory.js:761:90) 
    at DebugAppView.AppView.detectChanges (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:12586:18) 
    at DebugAppView.detectChanges (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:12691:48) 
    at DebugAppView.AppView.detectViewChildrenChanges (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:12612:23) 
    at DebugAppView._View_FindPageComponent0.detectChangesInternal (FindPageComponent.ngfactory.js:41:8) 
    at DebugAppView.AppView.detectChanges (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:12586:18) 
    at DebugAppView.detectChanges (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:12691:48) 
    at DebugAppView.AppView.detectViewChildrenChanges (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:12612:23) 
    at DebugAppView.AppView.detectChangesInternal (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:12597:18) 
ERROR CONTEXT: 
[object Object] 

为什么我得到那个错误?

变为AfterViewInit后,我现在收到此错误:

platform-browser.umd.js:937 Error: Uncaught (in promise): EXCEPTION: Error in app/find-page/find-form.component.html:13:30 
ORIGINAL EXCEPTION: TypeError: Cannot read property 'length' of undefined 
ORIGINAL STACKTRACE: 
TypeError: Cannot read property 'length' of undefined 
    at DebugAppView._View_FindFormComponent0.detectChangesInternal (FindFormComponent.ngfactory.js:890:72) 
    at DebugAppView.AppView.detectChanges (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:12586:18) 
    at DebugAppView.detectChanges (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:12691:48) 
    at DebugAppView.AppView.detectViewChildrenChanges (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:12612:23) 
    at DebugAppView._View_FindPageComponent0.detectChangesInternal (FindPageComponent.ngfactory.js:41:8) 
    at DebugAppView.AppView.detectChanges (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:12586:18) 
    at DebugAppView.detectChanges (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:12691:48) 
    at DebugAppView.AppView.detectViewChildrenChanges (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:12612:23) 
    at DebugAppView.AppView.detectChangesInternal (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:12597:18) 
    at DebugAppView.AppView.detectChanges (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:12586:18) 
ERROR CONTEXT: 
[object Object] 
    at resolvePromise (http://localhost:3000/node_modules/zone.js/dist/zone.js:538:32) 
    at http://localhost:3000/node_modules/zone.js/dist/zone.js:515:14 
    at ZoneDelegate.invoke (http://localhost:3000/node_modules/zone.js/dist/zone.js:323:29) 
    at Object.onInvoke (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:9245:45) 
    at ZoneDelegate.invoke (http://localhost:3000/node_modules/zone.js/dist/zone.js:322:35) 
    at Zone.run (http://localhost:3000/node_modules/zone.js/dist/zone.js:216:44) 
    at http://localhost:3000/node_modules/zone.js/dist/zone.js:571:58 
    at ZoneDelegate.invokeTask (http://localhost:3000/node_modules/zone.js/dist/zone.js:356:38) 
    at Object.onInvokeTask (http://localhost:3000/node_modules/@angular/core//bundles/core.umd.js:9236:45) 
    at ZoneDelegate.invokeTask (http://localhost:3000/node_modules/zone.js/dist/zone.js:355:43) 

的错误似乎是在FindFormComponent。

FindFormComponent只是具有多选(表单填写,然后将查找产品)的形式。

下面是从FindFormComponent有关HTML利用长度:

<div class="row has-error-text"> 
    <div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-lg-4 offset-lg-4 input-group btn-group" style="height:64px;"> 
     <div style="position: relative; display: inline-block; width: 100%;"> 
      <multiselect #multiselect></multiselect> 
     </div> 
    </div> 
</div> 
<div class="row error-text" [style.display]="multiselect.selectedCategories.length < 1 && submitted ? 'block' : 'none'"> 
    <div class="col-sm-8 offset-sm-2 col-md-6 offset-md-3 col-lg-4 offset-lg-4 form-group input-group btn-group"> 
     <small>Please select at least 1 category.</small> 
    </div> 
</div> 

回答

5

您需要更改

ngOnInit() { 
    this.selectedCategories = []; 
    this.select.nativeElement.multiselect({ 

ngAfterViewInit() { 
    this.selectedCategories = []; 
    this.select.nativeElement.multiselect({ 

nativeElement不可用前视图被初始化。

+0

谢谢。它现在有另一个错误。无法读取未定义的属性长度。也许它是指我的“changed()”函数中的“长度”。所以我selectedCategries数组的长度。虽然我不确定。我现在要在这个问题上发布错误。 – BeniaminoBaggins

+0

我想不是因为你把它设置为'[]'。很难说。你可以请编辑你的问题,并在那里添加更多的细节(确切的错误消息,堆栈跟踪) –

+0

堆栈跟踪似乎表明该异常与表单元素有关,但我不知道可能导致它的原因。 –

相关问题