Angular:无法读取属性' name'未定义的

时间:2018-01-29 08:14:16

标签: angular

在我的angular 4应用程序中,每次我的侧边栏组件呈现时,我都会收到这个奇怪的错误。我没有任何属性" name"在我的代码中。发现很难弄清楚错误被抛出的原因。以下是控制台错误日志。任何帮助深表感谢。

html代码:

<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>

2 个答案:

答案 0 :(得分:14)

我刚刚得到了这个问题,似乎错误本身就是一个红色的鲱鱼,因为错误是角度的错误,请检查以下问题以获取更多内容

实际的潜在错误很可能是expressionChangedAfterItHasBeenCheckedError。在开发模式下,angular会超过绑定两次,第二次检查它们是否具有相同的值。如果它们没有相同的值,则假定读取值修改了那些绑定并因此抛出expressionChangedAfterItHasBeenCheckedError - 该异常的其他来源可能是如果您有非常不稳定的值,这些值经常变化,请尝试删除绑定,而不是错误应该消失,而不是你确定它是expressionChangedAfterItHasBeenCheckedError

长话短说,不关心您发布的例外情况,尝试解决expressionChangedAfterItHasBeenCheckedError(谷歌如何发生并得到解决 - 有很多问题已经在SO上发布了)

答案 1 :(得分:0)

您的方法isDetailsMenu()必须包含一个试图使用自己的name属性的变量。

在做某事之前,您应该始终测试变量。

isDetailsMenu() {
  return this.myVar && this.myVar.name === 'dtl';
}