组件共享数据时,无法读取未定义的值?

时间:2018-04-15 23:35:44

标签: javascript angular

我无法使用从服务中调用getbyId()方法收到的数据来填充表单,在我的控制台中我看到错误:无法读取未定义的truckId,我发现的每个解决方案都在说我的使用getById()方法得到的表单比我想要的对象更快,解决方案应该是* ngIf =“truck”,应该使表单等待,但它不解决它只是拒绝显示表单就这样。在下面的stackblitz How can I sync two flatList scroll position in react native

但是在控制台中我可以看到URL,当我打开它时,我看到它实际上从我的后端获得了详细信息 的服务

getTruckById(id: number): Observable<Truck> {
   const url = `${this.baseUrl}/${id}`;
    return this.http.get(url, {headers: this.headers})
      .pipe(map(this.extractData),
        tap(data => console.log(JSON.stringify(data))),
        catchError(this.handleError));
  } 

这是编辑组件完全

export class EditTruckComponent implements OnInit {
  five : number = 5;
  seven: number = 7;

 @Input() truck: Truck;

  truckIdTOUpdate: number;
  processValidation = false;
  dates: string;
  statusCode: number;
  requestProcessing = false;

   truckForm = new FormGroup({
    truckCode: new FormControl(Validators.maxLength(this.seven), Validators.minLength(this.five)),
    date: new FormControl('', Validators.required  ),
    descriptions: new FormControl(Validators.maxLength(this.seven), Validators.minLength(this.five))
  });


  constructor( private route: ActivatedRoute, private truckService: TruckService, private router: Router) {
  }

  ngOnInit() {
     this.getTruckDetail();
  }

  back() {
    this.router.navigate(['/trucks'])
  }

  getTruckDetail() {
    const truckId = +this.route.snapshot.paramMap.get('truckId');
   this.truckService.getTruckById(truckId)
      .subscribe((truck) => this.truck = truck)
      console.log("this is the truck" + this.truck);
  }

  processForm() {
    this.processValidation = true;
    if (this.truckForm.invalid) {
      return; //Validation failed, exit from method.
    }
    // if we are here then all good
    this.preProcessConfigurations()

    let truckCode = this.truckForm.get('truckCode').value.trim();
    let date = this.truckForm.get('date').value.trim();
    let description = this.truckForm.get('descriptions').value.trim();

    if (this.truck.truckId == undefined) {
      let truck = new Truck(null, truckCode,  date , description);

      this.truckService.createTruck(truck).subscribe((truck) => {
        console.log(truck)
        this.router.navigate(['/trucks']);
      }, errorCode => this.statusCode = errorCode);

    } else {
        this.truck = new Truck(this.truck.truckId, truckCode, date, description);
      this.truckService.updateTrucks(this.truck).subscribe((truck)=> {
        console.log(truck);
        this.router.navigate(['/trucks']);
      }, errorCode => this.statusCode = errorCode);
    }
  }

  //Perform preliminary processing configurations
  preProcessConfigurations() {
    this.statusCode = null;
    this.requestProcessing = true;
  }

}


   class="btn btn-light"
           title="Save Truck"
           data-toggle="tooltip"
           data-placement="bottom">
          <i class="fa fa-save"></i> <span class="d-none d-sm-inline" *ngIf="truck?.truckId ==undefined">Save</span>
          <span class="d-none d-sm-inline" *ngIf="truck?.truckId">Update</span>
        </a></li>
    </ul>
  </nav>
</header>

<section id="department">
  <div class="container-fluid">
    <div class="row">
      <div class="col">
        <div class="card">
          <div class="card-body">

            <form [formGroup]="truckForm" (ngSubmit)="processForm()"   id="editFormTruck" >
              <!--truck code-->
              <div class="form-group">
                <label class="form-control-label"
                       for="truckCode"></label>
                <input formControlName="truckCode"
                       id="truckCode"
                       class="form-control"
                       type="text"

                       name="truckCode"
                       min="2018-04-11" required
                       [(ngModel)]="truck?.truckCode"/> Truck Code
                <div class="alert alert-danger" role="alert"  *ngIf="truckForm.get('truckCode').invalid && processValidation" required="required" [ngClass] ="'error'">
                  you must have a minimum of 5 chars and maximum of 7
                </div>
                <div *ngIf="statusCode === 409" [ngClass] = "'success'" class="alert alert-danger" role="alert">
                  Truck with such Code already exists try another TruckCode.
                </div>

              </div>

              <!--purchasedDate-->
              <div class="form-group" >
                <label class="form-control-label"  *ngIf="truckForm.get('date').invalid && processValidation"  [ngClass] ="'error'"
                       for="purchasedDate">date is required.</label>
                <input formControlName="date"
                       id="purchasedDate"
                       class="form-control"
                        type="date"
                        name="purchasedDate"
                       [(ngModel)]="truck?.purchasedDate "
                /> Purchased Date
              </div>

我已发布所有内容,因为未定义的值从我的按钮的保存和更新开始,当我删除它时,它归结为truckCode未定义

为了更好地理解这是我的truckComponent导航到EditTruckComponent MY truckComponent显示卡车列表以及编辑和删除功能 现在在我的编辑功能在HTML我有一个我只有一个路由器链接

<tr *ngFor="let truck of trucks | async">
              <td>{{truck.truckId}}</td>
              <a routerLink="/truckProfile/">
              <td>{{truck.truckCode}}</td>
              </a>
              <td>{{truck.purchasedDate | date: 'yyyy-MM-dd'}}</td>
              <td>{{truck.descriptions}}</td>
              <td class="text-right">
                <a class="btn-sm btn-outline-secondary"
                   ngbTooltip="Edit Truck"
                   placement="top">
                  <i class="fa fa-bus"></i> <span
                  class="d-none d-md-inline" routerLink="/editsTrucks/{{truck.truckId}}"  >Edit</span></a>

                 <span data-toggle="modal" data-target="#deleteDialog">
                                <a href="#" class="btn-sm btn-outline-secondary"
                                 ngbTooltip="delete truck"
                                 placement="top">
                                    <i class="fa fa-remove"></i>
                                <span class="d-none d-md-inline"  (click)="deleteTruck(truck)">Delete</span></a>
                </span>
              </td>

所以我只需要使用路由器链接和我的editTruckCompnent进行导航即可在init上执行getById

2 个答案:

答案 0 :(得分:7)

问题出在我的java控制器

 @GetMapping(value = "/trucks/{truckId}")
    @ResponseStatus(HttpStatus.OK)
    public final TruckDto getTruckId(@PathVariable(value = "truckId")
                                         final Integer truckId) {

        LOGGER.debug("test: truckId({})", truckId);
        Truck truck = truckService.getTruckById(truckId);
        return mappingService.map(truck, TruckDto.class);
    }

当我添加这个注释时,它工作了@ResponseBody 因此响应主体告诉控制器返回的对象应序列化为JSON并传递回HttpResponse对象。 这就是我得到HttpResponse失败的原因

答案 1 :(得分:2)

这是一个设计问题。在我看来,正确的做法是:

EditTruckComponent parent应该是智能的,进行http调用并将卡车传递给EditTruckComponent(您可以使用异步,这样您就不必订阅和取消订阅)

以下是我如何想象父组件的线索:

<app-edit-truck [truck]="truck$ | async"></app-edit-truck>

export class EditTruckParentComponent {
    truck$: Observable < Truck > ;

    constructor(private truckService: TruckService) {
        this.truck$ = this.truckService.getTruckById(truckId);
    }
}

使EditTruckComponent哑,没有服务电话,只有输入和输出。实施OnChanges以处理卡车输入变化,并修补表格值。

编辑卡车组件如下所示:

export class EditTruckParent implements OnChanges {
    @Input() truck: Truck;
    constructor() {
    }

    ngOnChanges() {
        this.truckForm.patchValue(truck);
    }
}