为什么角度同步我的变量没有与 ngModel 绑定?



早上好, 几周前,我开始使用 Angular 进行开发。目前,我在使用 ngModel 时遇到了问题。

Component.ts:

import { Component, OnInit, Input, ElementRef } from '@angular/core';
import { EventEmitter } from 'protractor';
@Component({
selector: 'app-toggle-search',
templateUrl: './toggle-search.component.html',
styleUrls: ['./toggle-search.component.css']
})
export class ToggleSearchComponent implements OnInit {
constructor(private element: ElementRef) { }
searchTerm = "";
ngOnInit(): void {
}
toggleUserSubmittedSearchEvent() {
this.element.nativeElement
.dispatchEvent(new CustomEvent('userSubmittedSearch', {
detail: this.searchTerm,
bubbles: true
}));
}
showSearchBar(){
let searchbar = document.getElementById('searchBar');
let size = window.innerWidth; 
searchbar.style.display = "inline-block";
searchbar.style.width = (size < 600 ? 150 : size/4).toString() + "px"; 
}
hideSearchBar(){
document.getElementById('searchBar').style.display = "none";
}
}

.HTML:

<form 
class="search" 
(submit)="this.toggleUserSubmittedSearchEvent()" 
onsubmit="return false"
(mouseover)="this.showSearchBar()"
(mouseout)="this.hideSearchBar()"
>        
<input [(ngModel)]="searchTerm" type="text" id="searchBar" placeholder="search"/>
<p>⚲</p>
</form>

函数toggleUserSubmittedSearchEvent()应调度一个包含用户输入searchterm的事件。varsearchTerm应包含输入标记中输入的字符串。我的问题是 Angular 不会searchTerm与输入标签同步。我错过了什么?

您需要做的是将name属性添加到input字段中

<input [(ngModel)]="searchTerm" name="search"

或将此属性添加到[ngModelOptions]="{standalone: true}

否则,您应该在浏览器的控制台中收到以下错误消息

Error: If ngModel is used within a form tag, either the name attribute must be set or the form
control must be defined as 'standalone' in ngModelOptions.
Example 1: <input [(ngModel)]="person.firstName" name="first">
Example 2: <input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}">

更多信息在这里:

将 [(ngModel(] 与表单结合使用时,定义名称属性是一项要求。

当你像这样使用ngModel时,你需要在输入中添加一个名称,你需要使用插值来显示数据。

<input [(ngModel)]="searchTerm" type="text" id="searchBar" placeholder="search" name="input"/>
<p>⚲{{ searchTerm }}</p>

代码中还有其他问题,但这些问题不会影响该部分。 但是,请记住,EventEmitter必须从@angular/core导入,而不是从测试库protractor导入。

在 Angular 中,像你一样直接访问 DOM 是一种不好的做法。使用ViewChild装饰器和渲染器2服务。

更新

使用 Renderer2,您可以在不直接接触 DOM 的情况下操作元素。

为了更好地了解此服务,请查看以下链接:

  • 官方文档
  • Renderer2 服务的精彩解释

最新更新