无法准备未定义的属性

时间:2018-11-02 03:46:15

标签: angular angular6

从下拉列表中选择一个应用程序后,用户可以选择从下拉列表中选择一个导航或添加一个新的导航。

如果用户从下拉列表中选择一个导航,则该导航的相应详细信息应填写在表格中。并且,如果用户单击“添加新菜单”按钮,则应在同一表单中填充所有字段为空。

用户单击“添加新菜单”按钮时出现的错误是“无法读取未定义的属性'NavName'”。我尝试在OnInit方法中初始化Navigation项,但这没有帮助。

代码如下:

application.component.html

<mat-form-field>
  <mat-select placeholder="applications">
    <mat-option (click)="sendChangedId(app.Id)"  *ngFor="let app of apps" [value]="app.Id">
      {{app.ApplicationName}}
    </mat-option>
  </mat-select>
</mat-form-field>

application.component.ts

import { Component, OnInit, AfterViewInit } from '@angular/core';
import { ApplicationService } from '../application.service';
import { IApplication } from '../IApplication';
import { ShareAppIDService } from '../share-app-id.service';

@Component({
  selector: 'app-application',
  templateUrl: './application.component.html',
  styleUrls: ['./application.component.css']
})
export class ApplicationComponent implements AfterViewInit {
  apps: Array<IApplication>;

  constructor(private applicationService: ApplicationService, private shareAppIdService: ShareAppIDService) { }

  ngAfterViewInit() {
    this.applicationService
      .getApplications()
      .subscribe(data => {this.apps = data; } );
  }

  sendChangedId(appId) {
    this.shareAppIdService.changeAppId(appId);
    console.log('app id from app controller is ' + appId);
  }
}

share-app-id.service.ts

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ShareAppIDService {

  constructor() { }

  private appId = new Subject();
  public appIdChanged = this.appId.asObservable();

  public changeAppId(value) {
    this.appId.next(value);
    console.log('app id from changeAppId service is ' + value);
  }
}

navigation.component.html

<mat-form-field>
  <mat-select placeholder="navigations" >
  <mat-option (click)="sendChangedNav(nav)" *ngFor="let nav of navigations" [value]="nav.Id">
    {{nav.NavName}}
  </mat-option>
</mat-select>
</mat-form-field>
<br/>
<div *ngIf="appId > 0">
<button (click)="sendChangedNavDetail(appId)">Add New Menu Item</button>
</div>
<app-navigation-detail></app-navigation-detail>

navigation.component.ts

import { Component, OnInit, AfterViewInit, Input } from '@angular/core';
import { NavigationService } from '../navigation.service';
import { INavigation } from '../INavigation';
import { ShareAppIDService } from '../share-app-id.service';
import { ShareNavigationService } from '../share-navigation.service';

@Component({
  selector: 'app-navigation',
  templateUrl: './navigation.component.html',
  styleUrls: ['./navigation.component.css']
})
export class NavigationComponent implements AfterViewInit {
  navigations: Array<INavigation>;
  appId: number;

  constructor(private navigationService: NavigationService, private shareAppIdService: ShareAppIDService,
    private sharedNavService: ShareNavigationService) { }

  ngAfterViewInit() {
    this.shareAppIdService.appIdChanged.subscribe((appId: number) => {
      this.appId = appId;
      this.navigationService
        .getNavigations(appId)
        .subscribe(data => {this.navigations = data; });
        console.log(this.appId);
    });
  }

  sendChangedNav(nav) {
    this.sharedNavService.changeNavigation(nav);
  }

  sendChangedNavDetail(appId) {
    this.sharedNavService.updateNavigationDetail(true);
    this.shareAppIdService.changeAppId(appId);
  }
}

share-navigation.service.ts

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import { INavigation } from './INavigation';

@Injectable({
  providedIn: 'root'
})
export class ShareNavigationService {

  constructor() { }

  private navigation = new Subject<INavigation>();
  public navigationChanged = this.navigation.asObservable();

  private showNavigationDetail = new Subject<boolean>();
  public navigationDetailChanged = this.showNavigationDetail.asObservable();

  public changeNavigation(value) {
    this.navigation.next(value);
    console.log('navigation from changeNavigation service is ' + value);
  }

  public updateNavigationDetail(value) {
    this.showNavigationDetail.next(value);
  }
}

navigation-detail.component.html

<div *ngIf="navigation != null || showNavDetail">
<form>
  <label for="navName">Navigation Name</label>
  <br/>
  <input type="text" name="navName" [(ngModel)]="navigation.NavName" >
  <br/>
  <label for="navId">Nav ID</label>
  <br/>
  <input type="text" name="navId" [(ngModel)]="navigation.NavId" >
  <br/>
  <label for="navParentCode">Nav Parent Code</label>
  <br/>
  <input type="text" name="navParentCode" [(ngModel)]="navigation.NavParentId">
  <br/>
  <label for="navPageURL">Page URL</label>
  <br/>
  <input type="text" name="navPageURL" [(ngModel)]="navigation.NavPageURL">
  <br/>
  <label for="navPosition">Position</label>
  <br/>
  <input type="text" name="navPosition" [(ngModel)]="navigation.NavPosition">
  <br/>
  <label for="navRoleAccess">Role Access</label>
  <br/>
  <input id="textboxid" type="text" name="navRoleAccess" [(ngModel)]="navigation.NavRoleId">
  <br/>
  <label for="navTargetPage">Target Page</label>
  <br/>
  <select [(ngModel)]="navigation.NavTarget">
    <option>_target</option>
    <option>_blank</option>
    <option>_parent</option>
  </select>
  <br/>
  <input type="checkbox" [id]="navigation.NavActive" [name]="navigation.NavActive"
    [checked]="navigation.NavActive === 'Y' ? true:false"
    (change)="onActiveChange(navigation, $event)">Navigation Active
  <br/>
  <input type="checkbox" [id]="navigation.NavDesktop" [name]="navigation.NavDesktop"
    [checked]="navigation.NavDesktop === 'Y' ? true:false"
    (change)="onDesktopChange(navigation, $event)">Desktop View
  <br/>
  <input type="checkbox" [id]="navigation.NavTablet" [name]="navigation.NavTablet"
    [checked]="navigation.NavTablet === 'Y' ? true:false"
    (change)="onTabletChange(navigation, $event)">Tablet View
  <br/>
  <input type="checkbox" [id]="navigation.NavPhone" [name]="navigation.NavPhone"
    [checked]="navigation.NavPhone === 'Y' ? true:false"
    (change)="onPhoneChange(navigation, $event)">Phone View
  <br/>
  <button type="submit" (click)="onSubmit(navigation)">Save</button>
</form>
</div>

navigation-detail.component.ts

import { Component, OnInit, Input, AfterViewInit } from '@angular/core';
import { ValueTransformer } from '@angular/compiler/src/util';
import { INavigation } from '../INavigation';
import { ShareNavigationService } from '../share-navigation.service';
import { ShareAppIDService } from '../share-app-id.service';

@Component({
  selector: 'app-navigation-detail',
  templateUrl: './navigation-detail.component.html',
  styleUrls: ['./navigation-detail.component.css']
})
export class NavigationDetailComponent implements OnInit, AfterViewInit {
  navigation: INavigation;
  showNavDetail: boolean;

  constructor(private sharedNavService: ShareNavigationService,
      private sharedAppService: ShareAppIDService
    ) {
      // this.navigation.NavName = '';
    }

    ngOnInit() {
      this.navigation.NavName = '';
    }

  ngAfterViewInit() {

    this.sharedNavService.navigationChanged.subscribe((navigation) => {
      if (navigation != null) {
      this.navigation = navigation;
      console.log('navigation detail id is: ' + navigation.NavPageURL);
      navigation.NavTarget = navigation.NavTarget;
      console.log('navActive' + navigation.NavActive);
      }
    });


    this.sharedAppService.appIdChanged.subscribe((appId: number) => {
      console.log('appId in nav detail is' + appId);
      // this.navigation.NavAppId = appId;
    });

    this.sharedNavService.navigationDetailChanged.subscribe((data) => {
      console.log('show nav detail is' + data);
      this.showNavDetail = data;
    });
  }

  onActiveChange(navigation, event) {
    this.navigation.NavActive = event.target.checked ? 'Y' : 'N';
  }

  onDesktopChange(navigation, event) {
    this.navigation.NavDesktop = event.target.checked ? 'Y' : 'N';
  }

  onTabletChange(navigation, event) {
    this.navigation.NavTablet = event.target.checked ? 'Y' : 'N';
  }

  onPhoneChange(navigation, event) {
    this.navigation.NavPhone = event.target.checked ? 'Y' : 'N';
  }

  onSubmit(navigation) {
    alert('Submitting data:' + JSON.stringify(navigation));
  }

}

0 个答案:

没有答案