将angular 8应用迁移到9的奇怪问题

时间:2020-02-08 15:55:02

标签: angular

我正在将应用程序从8号角迁移到9号角。如果我尝试为部署而构建,则会收到此错误消息

ERROR : Cannot assign value "$event" to template variable "value". Template variables are read-only.
    at _AstToIrVisitor.visitPropertyWrite (...\node_modules\@angular\compiler\bundles\compiler.umd.js:8617:31)
    at PropertyWrite.visit (...\node_modules\@angular\compiler\bundles\compiler.umd.js:7459:28)
    at convertActionBinding (...\node_modules\@angular\compiler\bundles\compiler.umd.js:8224:49)
    at prepareEventListenerParameters (...\node_modules\@angular\compiler\bundles\compiler.umd.js:16861:27)
    at Object.params (...\node_modules\@angular\compiler\bundles\compiler.umd.js:17952:24)
    at ...\node_modules\@angular\compiler\bundles\compiler.umd.js:17725:94
    at Array.map (<anonymous>)
    at ...\node_modules\@angular\compiler\bundles\compiler.umd.js:17725:60
    at ...\node_modules\@angular\compiler\bundles\compiler.umd.js:17014:87
    at Array.map (<anonymous>)
    at TemplateDefinitionBuilder.buildTemplateFunction (...\node_modules\@angular\compiler\bundles\compiler.umd.js:17014:60)
    at ...\node_modules\@angular\compiler\bundles\compiler.umd.js:17558:60
    at ...\node_modules\@angular\compiler\bundles\compiler.umd.js:16992:81
    at Array.forEach (<anonymous>)
    at TemplateDefinitionBuilder.buildTemplateFunction (...\node_modules\@angular\compiler\bundles\compiler.umd.js:16992:37)
    at Object.compileComponentFromMetadata (...\node_modules\@angular\compiler\bundles\compiler.umd.js:18643:58)

我如何发现问题发生了?

15 个答案:

答案 0 :(得分:20)

替换代码种类

*ngFor="let movement of allowedMovements" [(value)]="movement" 

*ngFor="let movement of allowedMovements; let i = index" [(value)]="allowedMovements[i]"

答案 1 :(得分:14)

最终解决了问题。 我发现将其添加到tsconfig的问题。 json

  "angularCompilerOptions": {
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true
  }

我不确定这是否会自动添加到新项目的tsconfig.json中,但是我的项目中没有该内容。
启用这些选项后,我能够在编译器日志中看到错误并予以解决。

答案 2 :(得分:3)

正如其他人所说的那样,“模板变量是只读的”是双向绑定

与角度8配合使用

  [(ngModel)] 
  [(value)]

在角度9中引发错误

  [(ngModel)] 
  [(value)]

与角度9配合使用

  [ngModel]
  (ngModel)
  [value]

在我的情况下,我错误地将ngModel放在* ngFor内,而它恰好有一个$ event

在角度9中抛出错误

 <ng-container *ngFor="let color of palette; let i = index">
 <mat-form-field class="colorbtn">
   <input matInput type="color" [(value)]="color" 
    [(ngModel)]="color + i" (change)="Color($event, i)">
 </mat-form-field>
</ng-container>

与角度9配合使用

<ng-container *ngFor="let color of palette; let i = index">
 <mat-form-field class="colorbtn">
   <input matInput type="color" [value]="color" (ngModel)="color + i" (change)="Color($event, i)">
 </mat-form-field>
</ng-container>

答案 3 :(得分:3)

我收到此错误消息:

    <input id="inputPassword" name="inputPassword"
        [(ngModel)]="password" required #password="ngModel">

然后我用一个对象(或其他名称)替换了密码变量,它解决了该问题。

   <input id="inputPassword" name="inputPassword"
        [(ngModel)]="user.password" required #password="ngModel">

答案 4 :(得分:2)

不要同时使用 [(ngModel)]="password"#password。我遇到了同样的错误,只是修复了删除 #password

答案 5 :(得分:1)

听起来您好像在某个地方有一些html

<input #value (click)="value = $event" />

其中输入是某些元素,(单击)是某些事件处理程序。 (我以输入和单击为例,该错误消息并未说明其实际含义)

尝试查看代码中使用模板变量的所有位置(在本例中为#value),并尝试以某种方式在事件处理程序中为其分配事件结果。

编辑:

这是否意味着您在运行开发环境时没有看到此错误?如果是这样,这是否意味着您的开发环境中没有aot编译?我认为v9现在默认会将aot设置为true。至少当我最近升级时,它对我有用。

答案 6 :(得分:1)

我的问题来自Angular Material中mat-option的错误使用。

在Angular 8中,此代码很好:

<mat-select formControlName="qualityStatus" required (selectionChange)="onChangeQualityStatus($event)">
                    <mat-option *ngFor="let movement of allowedMovements" [(value)]="movement">
                        {{movement.qualityStatusDescription}}
                    </mat-option>
</mat-select>

,但是在Angular 9中,[(value)]="movement"将引发错误。该代码应仅为[value]="movement"。内部括号不正确,导致编译器说您正在分配给变量。 Angular 8忽略了这个问题。

希望这对其他人有帮助。

答案 7 :(得分:1)

正如错误所暗示的那样,模板变量是只读的,因此您不能将模型绑定到模板变量,而是可以绑定到组件属性。

就我而言,在 Angular 11 中,我将输入字段绑定到模板变量(即 [(ngModel)]="UserNameSearch")而不是组件属性,因为我的属性名称与模板变量相同。我将我的组件属性更改为驼峰式大小写并使用它进行绑定并且它起作用了。

之前:[(ngModel)]="UserNameSearch"(绑定到模板变量) Binding property name same as template variable

之后:[(ngModel)]="userNameSearch"(绑定到组件属性)

Binding property name different than template variable

答案 8 :(得分:1)

确保您没有将 DOM 中的 HTML 元素命名为与 ngModel 引用相同的名称。

这将产生错误:

<select class="custom-select mr-sm-2" id="myVariable" name="myVariable" [(ngModel)]="myVariable" #myVariable="ngModel" required>

将 HTML DOM 中的元素更改为不同的东西为我修复了它。

<select class="custom-select mr-sm-2" id="myVariableHtml" name="myVariableHtml" [(ngModel)]="myVariable" #myVariableHtml="ngModel" required>

答案 9 :(得分:0)

启用AOT: angular.json >>建筑师>>构建>>选项>>“ aot”:true

添加: “ angularCompilerOptions”:{ “ fullTemplateTypeCheck”:是的, “ strictInjectionParameters”:true }, 到tsconfig.json

这样,您应该可以看到错误在哪里

答案 10 :(得分:0)

使用aot进行编译以查看所有运行时错误

ng serve --aot

答案 11 :(得分:0)

#userName="ngModel" name="userName" [(ngModel)]="userName"

#userName value with [(ngModel)]="userName" should not be same
id change property in component.ts to
modelUserName :strgin;

#userName="ngModel" name="userName" [(ngModel)]="modelUserName"

答案 12 :(得分:0)

我正在使用ngFor进行下拉控制,并且在升级到Angular 9版本时遇到此错误。 问题是,下拉选项不需要圆括号

之前 [(ngValue)] =“ listItem”

之后 [ngValue] =“ listItem”

答案 13 :(得分:0)

我得到这个错误

$2

然后我以这种方式解决了,在日期绑定中添加了模型。

#!/bin/sh
if [ "$#" -ne 2 ]; then
  echo "Usage: ./gac FILENAME COMMIT_MESSAGE" >&2
  exit 1
fi
git add $1
git commit -m "$2" # <-- here

答案 14 :(得分:0)

当组件通过双向数据绑定将其输入之一传递给子组件时,我已经看到了这一点。

public class MyComponent {
  @Input()
  public foo;
}

public class MyChildComponent {
  @Input()
  public bar;
}
<!-- Invalid -->
<my-child-component [(bar)="foo"/>

<!-- Valid -->
<my-child-component [bar]="foo"/>

输出绑定无效,因为Angular无法从组件内部分配foo的值。如果foo需要更改,则需要在MyComponent外部发出一个事件来更改该值。