ค้นหาเว็บไซต์

angular - รายการที่เลือกไม่เปลี่ยนแปลง


กำลังทำงานกับโปรเจค Angular 11 ที่สร้างขึ้นใหม่

app.component.html

<div *ngFor="let i of getItems()">
  <select (change)="onSelectionChange($event.target.value)">
    <option></option>
    <option>1</option>
    <option>2</option>
    <option>3</option>
    <option>4</option>
  </select>
</div>

แอป.คอมโพเนนต์.ทีเอส

export class AppComponent {
  
  getItems(): any[] {
    return [{a: 1}, {a: 2}, {a: 3}, {a: 4}];
  }

  onSelectionChange(event) {
    console.log(event);
  }
}

ทุกอย่างดูเหมือนจะปกติดี กล่องเลือกสี่กล่องสามารถมองเห็นได้ แต่ละกล่องมีค่าที่ว่างเปล่าและมีจำนวนเต็มสี่จำนวนในรายการแบบเลื่อน สิ่งแปลกคือเมื่อฉันเปิดรายการแบบเลื่อนและคลิกเพื่อเลือกค่า เหตุการณ์ onSelectionChanged() จะถูกเรียกใช้งาน แต่ค่าที่เลือกไม่ได้เปลี่ยนในกล่องเลือก

ส่วนประกอบการเลือกเริ่มทำงานตามที่คาดหวังหากฉันเปลี่ยนวิธี getItems() ให้ส่งคืนตัวเลขธรรมดาแทนวัตถุ ดังนี้:

getItems(): any[] {
  return [1, 2, 3, 4];
}

นอกจากนี้ ผมยังได้พฤติกรรมที่ถูกต้องโดยการลบเหตุการณ์ (change) ออกจากเครื่องหมาย HTML ด้วย (ในกรณีนี้ เหตุการณ์จะไม่ถูกเรียกใช้งาน)

ฉันกำลังทำงานกับการพึ่งพาเหล่านี้

"dependencies": {
  "@angular/animations": "~11.0.1",
  "@angular/common": "~11.0.1",
  "@angular/compiler": "~11.0.1",
  "@angular/core": "~11.0.1",
  "@angular/forms": "~11.0.1",
  "@angular/platform-browser": "~11.0.1",
  "@angular/platform-browser-dynamic": "~11.0.1",
  "@angular/router": "~11.0.1",
  "rxjs": "~6.6.0",
  "tslib": "^2.0.0",
  "zone.js": "~0.10.2"
},
"devDependencies": {
  "@angular-devkit/build-angular": "~0.1100.2",
  "@angular/cli": "~11.0.2",
  "@angular/compiler-cli": "~11.0.1",
  "@types/jasmine": "~3.6.0",
  "@types/node": "^12.11.1",
  "codelyzer": "^6.0.0",
  "jasmine-core": "~3.6.0",
  "jasmine-spec-reporter": "~5.0.0",
  "karma": "~5.1.0",
  "karma-chrome-launcher": "~3.1.0",
  "karma-coverage": "~2.0.3",
  "karma-jasmine": "~4.0.0",
  "karma-jasmine-html-reporter": "^1.5.0",
  "protractor": "~7.0.0",
  "ts-node": "~8.3.0",
  "tslint": "~6.1.0",
  "typescript": "~4.0.2"
}

คำตอบ #1

ใช้ trackBy เพื่อแก้ไขปัญหา แต่ละครั้งที่มีการตรวจจับการเปลี่ยนแปลง Angular จะเรนเดอร์เทมเพลตทั้งหมดใหม่และ i จะถูกประเมินค่าเป็นวัตถุแรกเสมอ

.html

<div>
    <select (change)="onSelectionChange ($event.target)">
       <option *ngFor="let i of getItems(); trackBy:identify"
       value="{{i.value}}">{{i.label}}</option>
    </select>
</div>

.ts

identify(index, item) {
   return item.label;
}

คำตอบ #2

คุณยังไม่ได้ระบุค่าหาสำหรับตัวเลือกที่เลือก หากคุณดีบักและดูค่าของ $event.target.value ผมคิดว่ามันจะว่าง

พยายามระบุค่าของตัวเลือกโดยใช้แอตทริบิวต์ ตัวอย่างจากที่นี่:

<mat-form-field appearance="fill">
 <mat-label>Cars</mat-label>
 <select matNativeControl required>
    <option value="volvo">Volvo</option>
    <option value="saab">Saab</option>
    <option value="mercedes">Mercedes</option>
    <option value="audi">Audi</option>
  </select>
</mat-form-field>