在我的angular 4应用程序中,每次我的侧边栏组件呈现时,我都会收到这个奇怪的错误.我的代码中没有任何属性“name”.发现很难弄清楚错误被抛出的原因.以下是控制台错误日志.任何帮助深表感谢.
<div class="sidebar" > <app-sidebar></app-sidebar> <div class="sidebar-background" style="background-image: url(assets/img/sidebar-1.jpg)"></div> </div>
错误日志:
ERROR TypeError: Cannot read property 'name' of undefined at checkBindingNoChanges (core.js:9912) at checkNoChangesNodeInline (core.js:13961) at checkNoChangesNode (core.js:13935) at debugCheckNoChangesNode (core.js:14764) at debugCheckDirectivesFn (core.js:14666) at Object.eval [as updateDirectives] (AppComponent.html:2) at Object.debugUpdateDirectives [as updateDirectives] (core.js:14648) at checkNoChangesView (core.js:13773) at callViewAction (core.js:14126) at execComponentViewsAction (core.js:14078) at checkNoChangesView (core.js:13776) at callWithDebugContext (core.js:15049) at Object.debugCheckNoChangesView [as checkNoChangesView] (core.js:14593) at ViewRef_.webpackJsonp.../../../core/esm5/core.js.ViewRef_.checkNoChanges (core.js:11584) at core.js:5903 View_AppComponent_0 @ AppComponent.html:2 proxyClass @ compiler.js:14645 webpackJsonp.../../../core/esm5/core.js.DebugContext_.logError @ core.js:14989 webpackJsonp.../../../core/esm5/core.js.ErrorHandler.handleError @ core.js:1501 (anonymous) @ core.js:5908 webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:365 webpackJsonp.../../../../zone.js/dist/zone.js.Zone.run @ zone.js:125 webpackJsonp.../../../core/esm5/core.js.NgZone.runOutsideAngular @ core.js:4681 webpackJsonp.../../../core/esm5/core.js.ApplicationRef.tick @ core.js:5908 (anonymous) @ core.js:5734 webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:365 onInvoke @ core.js:4733 webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:364 webpackJsonp.../../../../zone.js/dist/zone.js.Zone.run @ zone.js:125 webpackJsonp.../../../core/esm5/core.js.NgZone.run @ core.js:4550 next @ core.js:5734 schedulerFn @ core.js:4319 webpackJsonp.../../../../rxjs/Subscriber.js.SafeSubscriber.__tryOrUnsub @ Subscriber.js:239 webpackJsonp.../../../../rxjs/Subscriber.js.SafeSubscriber.next @ Subscriber.js:186 webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber._next @ Subscriber.js:126 webpackJsonp.../../../../rxjs/Subscriber.js.Subscriber.next @ Subscriber.js:90 webpackJsonp.../../../../rxjs/Subject.js.Subject.next @ Subject.js:55 webpackJsonp.../../../core/esm5/core.js.EventEmitter.emit @ core.js:4299 checkStable @ core.js:4698 onHasTask @ core.js:4746 webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.hasTask @ zone.js:418 webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate._updateTaskCount @ zone.js:438 webpackJsonp.../../../../zone.js/dist/zone.js.Zone._updateTaskCount @ zone.js:262 webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask @ zone.js:182 drainMicroTaskQueue @ zone.js:593 Promise resolved (async) scheduleQueueDrain @ zone.js:552 scheduleMicroTask @ zone.js:560 webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ zone.js:387 webpackJsonp.../../../../zone.js/dist/zone.js.Zone.scheduleTask @ zone.js:209 webpackJsonp.../../../../zone.js/dist/zone.js.Zone.scheduleMicroTask @ zone.js:229 scheduleResolveOrReject @ zone.js:758 webpackJsonp.../../../../zone.js/dist/zone.js.ZoneAwarePromise.then @ zone.js:847 webpackJsonp.../../../core/esm5/core.js.PlatformRef.bootstrapModule @ core.js:5562 ../../../../../src/main.ts @ main.ts:11 __webpack_require__ @ bootstrap 655e16dd1fe7443b4474:54 0 @ main.bundle.js:1835 __webpack_require__ @ bootstrap 655e16dd1fe7443b4474:54 webpackJsonpCallback @ bootstrap 655e16dd1fe7443b4474:25 (anonymous) @ main.bundle.js:1 AppComponent.html:2 ERROR CONTEXT
完整的TS:
import { Component,OnInit } from '@angular/core'; import { LabelsModel } from './../../core/models/labels'; import { LevelModel } from './../../core/models/level'; import { DataService } from './../../core/service/data.service'; import * as _ from 'underscore'; import { AppService } from './../../core/service/app.service'; import { CategoryModel } from './../../core/models/cat'; import { OnDestroy } from '@angular/core/src/Metadata/lifecycle_hooks'; import { AttributeModel } from './../../core/models/att'; import { CountModel,CountChildModel } from './../../core/models/count'; import { SearchModel } from './../../core/models/search'; declare const $: any; @Component({ selector: 'app-sidebar',templateUrl: './sidebar.component.html',styleUrls: ['./sidebar.component.css'] }) export class SidebarComponent implements OnInit { menuItems: any[]; highlightedDiv: number; productCategory: CategoryModel[]; productCategoryM: CategoryModel[]; productFiltered: AttributeModel[]; searchOrder = []; productAttribute: AttributeModel[]; productAttributeM: AttributeModel[]; countModel: CountModel[]; countChildModel: Array<CountChildModel> = []; countVal: any; data = []; searchArray = []; searchModel: SearchModel = {}; childSearch: string[] = []; productSelected: LevelModel; searchCheck: SearchModel[]; checkB: boolean; searchCheck1: SearchModel; // productName: string; filterSelected: boolean; labelList: LabelsModel[] = []; constructor(private _AppService: AppService,private _dataService: DataService) { } ngOnInit() { this._AppService.getData().subscribe(te => this.labelList = te); this._dataService.productSelectedName.subscribe(product => this.productChange(product)); this._dataService.toggleValue.subscribe(toggleVal => this.changeToggle(toggleVal)); this._AppService.getCat$().subscribe(categoryValues => this.processCategory(categoryValues)); this._dataService.filterList.subscribe(filterValue => this.changeFilter(filterValue)); this._dataService.setFilterSelected(false); this._dataService.filterSelect.subscribe(val => this.filterSelected = val); } isMobileMenu() { if ($(window).width() > 991) { return false; } else { return true; } }; changeToggle(toggle): void { this.highlightedDiv = toggle; } clearFilters() { this._dataService.setFilterList([]); this._dataService.setFilterSelected(false); this._dataService.setDisplay(0); } productChange(product) { this.productSelected = {}; if (product === undefined || product == null) { this.productSelected.level = 'level1'; this.productSelected.product = 'root'; } else { this.productSelected = product; } if (this.productCategoryM !== undefined) { this.processCategory(this.productCategoryM); } } processCategory(categoryValues): void { this.searchOrder = []; this.productCategory = _.where(categoryValues,{ id: this.productSelected.product }); this.productCategoryM = categoryValues; for (const search of this.productCategory[0].search) { this.searchOrder.push(search); } this._AppService.getAtt$().subscribe(attributeValues => this.processAttribute(attributeValues)); } processAttribute(attributeValues): void { const searchObj = {}; let filters = []; this.productFiltered = []; this.productAttributeM = attributeValues; this.searchCheck = this._dataService.getFilterList(); searchObj[this.productSelected.level] = this.productSelected.product; const searchKey = this.productSelected.level; this.productAttribute = _.where(attributeValues,searchObj); if (this._dataService.getFilterSelected() == true) { filters = this._dataService.getFilterList(); for (let i = 0; i < filters.length; i++) { for (let j = 0; j < filters[i].searchChild.length; j++) { if (isNaN(+filters[i].searchChild[j])) { searchObj[filters[i].searchParent] = filters[i].searchChild[j]; } else { searchObj[filters[i].searchParent] = +filters[i].searchChild[j]; } } } this.productFiltered.push.apply(this.productFiltered,(_.where(this.productAttribute,searchObj))); this.productAttribute = _.unique(this.productFiltered); } this.countModel = []; for (let i = 0; i < this.searchOrder.length; i++) { this.checkB = false; if (this.searchCheck !== undefined && this.searchCheck.length > 0) { this.searchCheck1 = this.searchCheck.find(this.check,this.searchOrder[i]); if (this.searchCheck1 !== undefined) { if (this.searchCheck1.searchChild.length > 0) { this.checkB = true; } } } this.countModel[i] = {}; this.countModel[i].parentName = this.searchOrder[i]; this.countVal = _.pairs(_.countBy(this.productAttribute,this.searchOrder[i])); this.countChildModel = []; for (let j = 0; j < this.countVal.length; j++) { if (this.countVal[j][0] !== 'null'){ this.countChildModel[j] = {}; this.countChildModel[j].childName = this.countVal[j][0]; this.countChildModel[j].count = this.countVal[j][1]; if (this.checkB) { if ((this.searchCheck.find(this.check,this.searchOrder[i]).searchChild.find (this.check1,this.countVal[j][0])) !== undefined) { this.countChildModel[j].check = true; } } } } this.countModel[i].child = _.sortBy(this.countChildModel,'childName'); } for (let i = 0; i < this.countModel.length; i++) { this.countModel[i].parentLabel = _.where(this.labelList,{ id: this.countModel[i].parentName })[0].label; } } check(ad) { return ad.searchParent == this ? true : false; } check1(ad2) { return ad2 == this ? true : false; } changeFilter(val) { val.length == 0 ? this._dataService.setFilterSelected(false) : this._dataService.setFilterSelected(true); this.processAttribute(this.productAttributeM); } taxonSelected(parent,taxon,checked) { this.searchModel = {}; this.childSearch = []; this.searchArray = []; if (checked) { this.searchArray = this._dataService.getFilterList(); if (_.where(this._dataService.getFilterList(),{ searchParent: parent }).length > 0) { this.childSearch = _.where(this._dataService.getFilterList(),{ searchParent: parent })[0].searchChild; this.searchArray.splice((this.searchArray.map(function (d) { return d['searchParent']; }).indexOf(parent)),1); this.childSearch.push(taxon.childName); this.searchModel.searchChild = this.childSearch; this.searchArray.push(this.searchModel); this.searchModel.searchParent = parent; this._dataService.setFilterList(this.searchArray); } else { this.childSearch.push(taxon.childName); this.searchModel.searchChild = this.childSearch; this.searchModel.searchParent = parent; this.searchArray.push(this.searchModel); this._dataService.setFilterList(this.searchArray); } } else { this.childSearch = _.where(this._dataService.getFilterList(),{ searchParent: parent })[0].searchChild; if (this._dataService.getFilterList().length > 1) { this.searchArray = this._dataService.getFilterList(); this.searchArray.splice((this.searchArray.map(function (d) { return d['searchParent']; }).indexOf(parent)),1); if (this.childSearch.length > 1) { this.childSearch.splice(this.childSearch.indexOf(taxon.childName),1); this.searchModel.searchChild = this.childSearch; this.searchModel.searchParent = parent; this.searchArray.push(this.searchModel); this._dataService.setFilterList(this.searchArray); } else { this._dataService.setFilterList(this.searchArray); } } else { if (this.childSearch.length > 1) { this.childSearch.splice(this.childSearch.indexOf(taxon.childName),1); this.searchModel.searchChild = this.childSearch; this.searchModel.searchParent = parent; this.searchArray.push(this.searchModel); this._dataService.setFilterList(this.searchArray); } else { this._dataService.setFilterList([]); } } } } ngOnDestroy(): void { } }
完整的side.HTML代码:
<div class="logo"> <a href="" class="simple-text"> <div class="logo-img"> <img src="" /> </div> Tenets Technologies </a> </div> <div class="sidebar-wrapper scrollbar-danger" > <div class="row"> <div class="col-lg-6 col-md-6 col-sm-6 refine "> <h6>Refine </h6> </div> <div class="col-lg-5 col-md-5 col-sm-5 clear text-right" (click) = "clearFilters()" *ngIf="filterSelected==true"> Clear All <i class="material-icons">clear</i> </div> </div> <div class="nav-container "> <ul class="nav "> <li routerlinkactive="active" *ngFor="let search of countModel" class=""> <a data-toggle="collapse" href="#{{search.parentName}}" class=""> <div class="row"> <div class="col-md-2 col-sm-2 col-xs-2 "> <i class="material-icons">apps</i> </div> <div class="col-xs-8 col-sm-8 col-md-8"> <p class="test"> {{search.parentLabel}}</p> </div> <div class="col-md-2 col-sm-2 col-xs-2 "> <b class="caret"></b> </div> </div> </a> <div class="collapse listCont scrollbar-danger" id="{{search.parentName}}"> <ul class="nav child"> <li routerlinkactive="active" *ngFor="let test of search.child"> <div class="checkBox"> <label> <input type="checkBox" name="optionsCheckBoxes" [checked]="test.check" (click)="taxonSelected(search.parentName,test,$event.target.checked)"> <span class="checkBox-label"> {{test.childName}} ({{test.count}}) </span> </label> </div> </li> </ul> </div> </li> </ul> </div> </div>
App.component.ts
import { Component,OnInit,ViewChild,AfterViewInit,ChangeDetectorRef } from '@angular/core'; import { Location,LocationStrategy,PathLocationStrategy,PopStateEvent } from '@angular/common'; import 'rxjs/add/operator/filter'; import { NavbarComponent } from './components/navbar/navbar.component'; import { Router,NavigationEnd,NavigationStart } from '@angular/router'; import { Subscription } from 'rxjs/Subscription'; import PerfectScrollbar from 'perfect-scrollbar'; import { DataService } from 'app/core/service/data.service'; import { MatSnackBar } from '@angular/material'; import { AppService } from 'app/core/service/app.service'; declare const $: any; @Component({ selector: 'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { private _router: Subscription; private lastPoppedUrl: string; private yScrollStack: number[] = []; /* headerValue = 0; */ toggleSide: number; @ViewChild(NavbarComponent) navbar: NavbarComponent; constructor(public location: Location,private router: Router,private _dataService: DataService,private cdr: ChangeDetectorRef,private _AppService:AppService ) { } ngOnInit() { $.material.init(); this._dataService.toggleValue.subscribe(toggle => this.changeToggle(toggle)); const elemMainPanel = <HTMLElement>document.querySelector('.main-panel'); const elemSidebar = <HTMLElement>document.querySelector('.sidebar .sidebar-wrapper'); this._dataService.setDisplay(0); /* this.headerValue = 0; this._dataService.headerValue.subscribe(header => this.headerValue = header); */ this.location.subscribe((ev: PopStateEvent) => { this.lastPoppedUrl = ev.url; }); this.router.events.subscribe((event: any) => { this.navbar.sidebarClose(); if (event instanceof NavigationStart) { if (event.url != this.lastPoppedUrl) this.yScrollStack.push(window.scrollY); } else if (event instanceof NavigationEnd) { if (event.url == this.lastPoppedUrl) { this.lastPoppedUrl = undefined; window.scrollTo(0,this.yScrollStack.pop()); } else window.scrollTo(0,0); } }); this._router = this.router.events.filter(event => event instanceof NavigationEnd).subscribe((event: NavigationEnd) => { elemMainPanel.scrollTop = 0; elemSidebar.scrollTop = 0; }); if (window.matchMedia(`(min-width: 960px)`).matches && !this.isMac()) { let ps = new PerfectScrollbar(elemMainPanel); ps = new PerfectScrollbar(elemSidebar); } } changeToggle(val) { this.toggleSide = val; this.isDetailsMenu(); } isDetailsMenu() { if (this.toggleSide == 1) { return false; } else { return true; } } ngAfterViewInit() { this.runOnRouteChange(); } runOnRouteChange(): void { if (window.matchMedia(`(min-width: 960px)`).matches && !this.isMac()) { const elemMainPanel = <HTMLElement>document.querySelector('.main-panel'); const ps = new PerfectScrollbar(elemMainPanel); ps.update(); } } isMac(): boolean { let bool = false; if (navigator.platform.toUpperCase().indexOf('MAC') >= 0 || navigator.platform.toUpperCase().indexOf('IPAD') >= 0) { bool = true; } return bool; } }
App.component.html
<div class="wrapper"> <div class="sidebar" > <app-sidebar></app-sidebar> <div class="sidebar-background" style="background-image: url(assets/img/sidebar-1.jpg)"></div> </div> <div class="main-panel" [ngClass]="{'dtl1': isDetailsMenu()}"> <app-navbar class="pos" [ngClass]="{'dtl-nav': isDetailsMenu()}"></app-navbar> <app-app-filter ></app-app-filter> <app-tree></app-tree> <router-outlet></router-outlet> <app-footer></app-footer> </div> </div>
我刚刚得到了这个问题,似乎错误本身就是一个红色的鲱鱼,因为错误是角度的错误,请检查以下问题以获取更多内容
原文链接:https://www.f2er.com/angularjs/141032.html> https://github.com/angular/angular/issues/21788
> https://github.com/angular/angular/issues/21735
> https://github.com/angular/angular/issues/21765
实际的底层错误很可能是表达式变化后的错误.持有错误.在开发模式下,angular会超过绑定两次,第二次检查它们是否具有相同的值.如果它们没有相同的值,则假定读取值修改了那些绑定,因此抛出了ExpressionChangedAfterItHasBeenCheckedError – 该异常的其他来源可能是如果您有非常不稳定的值,这些值经常变化,请尝试删除绑定,错误应该消失,而不是你确定它是expressionChangedAfterItHasBeenCheckedError