【问题标题】:Date not binding properly to Angular input property日期未正确绑定到 Angular 输入属性
【发布时间】:2020-02-29 11:13:28
【问题描述】:

我在我的 Angular 应用程序中制作了一个日历,我试图将用户单击的特定日期传递给子组件。子组件声明如下:

<app-day-view [date]="dateToPass | date:'yyyy-MM-dd'"></app-day-view>

并且子组件也被设置为正确接收输入属性:

import { Component, OnInit, Input, Output } from '@angular/core';
import { DateHandlerService } from './../../_services/date-handler.service';

declare var $: any;

@Component({
  selector: 'app-day-view',
  templateUrl: './day-view.component.html',
  styleUrls: ['./day-view.component.css']
})
export class DayViewComponent implements OnInit {

  @Input() date;
  dateString: string;
  constructor(public dateHandler: DateHandlerService) { }

  ngOnInit() {
    $('#dayModal').on('shown.bs.modal', this.getDateString);
  }

  getDateString() {
    //this.dateString = this.dateHandler.convertToOutDate(this.date);
  }
}

预期的行为是我单击日历中的某一天,&lt;app-day-view&gt;(这是一个模态)打开,获取 dateToPass(我已确认已存储正确的日期),并将其发送到子组件。这个模板不会抛出任何错误,但是当我检查DayViewComponent 中的日期时,它是未定义的。

我认为这是由父组件中存在的子组件在打开之前引起的问题。日期输入属性在技术上是未定义的,直到我单击日历中的某一天,之后它会突然被定义,但我不确定 Angular 输入属性是否像这样工作。为了解决这个问题,我使用 JQuery 检查模态的shown.bs.modal 事件,我只尝试使用该事件触发后的日期,但日期似乎仍然未定义。

【问题讨论】:

    标签: angular data-binding


    【解决方案1】:

    如果您的子日历组件在您实际上在dateToPass 中有值之前就已存在于DOM 中,那么undefined 将转到您的输入。

    我承认我不会经常使用管道,但这不会尝试将您的日期输入转换为字符串输入吗?如果您有 Date 作为输入,只需按原样给它 Date 对象,而不是尝试格式化它(除非组件实际上需要字符串输入)。

    除此之外,在您尝试查看该值时,在您的 ngOnInit 方法中,您没有向它传递任何值,除非您将该组件包装在 *ngIf 中。

    dateToPass 的任何后续更改都不会导致您再次点击 ngOnInit 方法 - 实际上只在组件初始化时点击一次,它已经被点击了。

    您可以挂钩到 Angular 的变更检测,或者将您的输入切换为 setter...

    @Input() public set date(value: Date) {
      this.onDateChanged(value);
    }
    
    private onDateChanged(date: Date): void {
      console.log(`Date value changed to: ${date}`);
    }
    

    如果您想确保您的组件具有输入值,则使用*ngIf 将其隐藏(实际上是将其从 dom 中删除,而不仅仅是将其“隐藏”):

    <div *ngIf="dateToPass">
      <app-day-view [date]="dateToPass"></app-day-view>
    </div>
    

    这将使 Angular 仅在您主动设置值后渲染(和初始化)您的组件 - 从而保证在 ngOnInit 上为您提供一个值供您检查。

    【讨论】:

    • 两个非常明智的解决方案。我在想,使用 JQuery 来侦听模式显示事件更像是订阅,因为它每次只需调用一次即可触发,无论组件是否已经初始化。我使用了变化检测方法,它似乎有效。我现在要读一点。感谢您的帮助。
    【解决方案2】:

    我认为问题是因为 ngOnit 值在开始时未定义,因为响应需要时间。

    使用 ngOnChanges() 代替 ngOnit

    只要console.log in ngOnChanges() 如果值来了,添加一个if条件

        ngOnChanges(){
        console.log(date);
         $('#dayModal').on('shown.bs.modal', this.getDateString);
        }
    
     getDateString() {
        if(date){
            //this.dateString = this.dateHandler.convertToOutDate(this.date);
          }
        }
    

    【讨论】:

      猜你喜欢
      • 2016-11-05
      • 2016-05-11
      • 2016-06-29
      • 2018-07-31
      • 2017-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多