【问题标题】:Angular Material Date Picker cannot be dynamically namedAngular Material Date Picker 不能动态命名
【发布时间】:2018-02-18 17:19:47
【问题描述】:

我正在动态生成一个表单,我需要根据模型命名我的控件。

我正在使用 Angular 5 和 Angular-Material 5。

但是,由于出现以下错误,我无法动态命名日期选择器 (Mat-DatePicker)。

InstrumentSearchComponent.html:27 错误类型错误: this._datepicker._registerInput 不是函数

这就是我尝试使用导致上述错误的动态名称创建控件的方式。

 <mat-form-field>
                        <input matInput [matDatepicker]="dynamicName" placeholder="{{ dynamicLabel }}">
                        <mat-datepicker-toggle matSuffix [for]="dynamicName"></mat-datepicker-toggle>
                        <mat-datepicker #{{dynamicName}}></mat-datepicker>
                    </mat-form-field>

dynamicNamedynamicLabel 在关联的 TS 文件中定义,并且来自我为字段定义的模型。

如果我删除动态名称并将它们全部替换为静态名称,例如 datePicker1 或 picker1,那么一切正常,但我正在努力组合静态命名控件并将其绑定到我的模型。

有效的静态命名控件示例。

 <mat-form-field>
                        <input matInput [matDatepicker]="picker" placeholder="{{ dynamicLabel }}">
                        <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
                        <mat-datepicker #picker></mat-datepicker>
                    </mat-form-field>

大家有什么建议吗?谢谢

【问题讨论】:

  • 为什么不使用id (id="{{dynamicName}}") 而不是模板变量 (#picker)?您可以很容易地获得对具有 id 的组件的引用。
  • 谢谢理查德;我最终在关联的输入字段上使用了 formControlName 。我的搜索表单上只有一个日期时间字段,所以我可以忍受。但是当我将有 2 个或更多日期控件时,我将不得不找到一种方法来命名两个日期选择器彼此不同:) 谢谢好友

标签: angular datepicker angular-material


【解决方案1】:

当将#identifier 分配给角度模板中的特定元素时,只需创建一个具有该名称的局部变量。因此,即使您使用相同的名称也没关系,因为它的范围仅限于该循环周期。

假设您正在根据数组 formData 中的某些数据动态创建表单

formData = [
    {
       id=0,
       type="date-picker",
       label= "label 1"
    }, 
    ...
]

在这种情况下,下面的代码应该可以完成您的工作。

<mat-form-field *ngFor="let field of formData">
    <input matInput [matDatepicker]="picker" placeholder="{{ field.Label }}">
    <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
    <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

随着每个循环的运行,#picker 会使用新的输入元素重新初始化,而新的输入元素又会传递给 [matDatepicker]

这与在 for 循环中重新初始化变量相同。

for(let i = 0; i < formData.length ; i++ ){

    // assume <mat-datepicker #picker></mat-datepicker> similar to below line of code.

    let picker = document.createElement("INPUT");
}

【讨论】:

  • 你能解释一下这实际上是如何工作的吗&lt;mat-datepicker #picker&gt;&lt;/mat-datepicker&gt;?它看起来像在循环中多次创建#picker相同 引用。 [for]="picker"[matDatepicker]="picker" 相同。为什么不能这样做,例如[matDatepicker]="{{ i + 'picker' }}" 区分一个选择器和另一个?
  • [matDatepicker] 需要一个变量而不是唯一的字符串值。如果您查看示例中给出的 for 循环,#picker 只不过是let picker,它被分配了一个引用该日期选择器的对象。在每次迭代中,变量 #picker 都会在该范围内使用新的 datepicker 对象重新初始化。
  • 在我的例子中,“范围”是关键字,到目前为止,我一直将它们视为“并排”的 相同 变量,而实际上它们的范围不同。求解释!
【解决方案2】:

从日期选择器中删除插值并直接使用动态模板引用名称。

<mat-form-field>
  <input matInput [matDatepicker]="dynamicName" placeholder="{{ dynamicLabel }}" />
  <mat-datepicker-toggle matSuffix [for]="dynamicName"></mat-datepicker-toggle>
  <mat-datepicker #dynamicName></mat-datepicker>
</mat-form-field>

【讨论】:

    【解决方案3】:

    如果动态日期选择器不是您所拥有的,并且您还为输入框创建了一个局部变量,请确保该变量的名称与您为日期选择器创建的局部变量不同。见下文:

    <mat-form-field>
      <mat-label>Choose a date</mat-label>
      <input matInput [matDatepicker]="datePicker" name="someDate" [ngModel]="someVariable.DATE" #dateRef="ngModel">
      <mat-datepicker-toggle matSuffix [for]="datePicker"></mat-datepicker-toggle>
      <mat-datepicker #datePicker></mat-datepicker>
    </mat-form-field>
    

    请注意,输入字段的局部变量名为 dateRef,而日期选择器的局部变量名为 datePicker,它们并不相同。

    【讨论】:

      【解决方案4】:

      在使用 angular 9 和材料的项目中启用 ivy 编译器后,我遇到了类似的问题。而且我不知道为什么这在禁用常春藤编译器的情况下有效。

      就我而言,问题在于模板中的变量名重复。

      <mat-form-field class="col-md-4">
            <mat-label>Birth Date: </mat-label>
            <input
              formControlName="birthDate"
              matInput
              [matDatepicker]="birthdt"
              (click)="birthdt.open()"
              (focus)="birthdt.open()"
              #birthdt   <==== HERE, after removed, works ?
            />
            <mat-datepicker-toggle
              matSuffix
              [for]="birthdt"
            ></mat-datepicker-toggle>
            <mat-datepicker
              startView="multi-year"
              [startAt]="startDate"
              touchUi
              #birthdt  <==== AND HERE
            ></mat-datepicker>
          </mat-form-field>
      

      所以,就是这样。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-02-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多