在Ember中用JavaScript修改JSON键值无效问题排查
id_update_status Hey there! The issue you're facing ties directly to Ember's reactivity system—plain JavaScript arrays and objects don't trigger template updates because they aren't tracked by Ember's change detection. Let's break down how to fix this step by step:
Why Your Current Approach Isn't Working
Ember relies on its tracking system (or older observable patterns) to know when to re-render templates. When you modify a regular JS object's property or a plain array, Ember has no way to detect that change, so your template stays stuck showing the old value.
Solutions Based on Ember Version
For Ember Octane+ (3.13+) (Recommended)
Octane uses @tracked decorators for built-in reactivity. Here's how to adjust your code:
Make your data trackable in the component's JavaScript file:
import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; export default class YourComponent extends Component { // Track the array itself @tracked adultJsonArr = []; constructor() { super(...arguments); // Convert raw data into objects with tracked properties this.adultJsonArr = this.args.adultData.map(item => ({ ...item, // Mark the property we need to update as tracked @tracked id_update_status: item.id_update_status })); } // Action to update the status @action updateIdStatus(index, newStatus) { // Directly assign the tracked property—Ember will detect the change this.adultJsonArr[index].id_update_status = newStatus; } }Wire the action to your template (example for a button/trigger):
{{#each adultJsonArr as |adultTravellerDetails index|}} {{my-s3-uploader class='uploader-button' onClick=(fn this.updateIdStatus index 'available')}} <div class="mdl-cell mdl-cell-6-col "> {{#if (eq adultTravellerDetails.id_update_status 'available')}} <p>UPDATE ID Proof</p> {{/if}} {{#if (eq adultTravellerDetails.id_update_status 'never_added')}} <p>ADD ID Proof</p> {{/if}} </div> {{/each}}
For Older Ember Versions (Pre-Octane)
If you're using an older Ember version, use Ember's observable objects and arrays:
Convert data to Ember-trackable structures:
import Ember from 'ember'; export default Ember.Component.extend({ // Initialize as an Ember Array (trackable) adultJsonArr: Ember.A(), init() { this._super(...arguments); let rawData = this.get('adultData'); // Convert each item to an Ember Object (observable) let emberizedData = rawData.map(item => Ember.Object.create(item)); this.set('adultJsonArr', emberizedData); }, actions: { updateIdStatus(index, newStatus) { // Fetch the traveller object with Ember's get method let traveller = this.get('adultJsonArr')[index]; // Use set() to update the property—this triggers reactivity traveller.set('id_update_status', newStatus); } } });Template usage with the old action helper:
{{#each adultJsonArr as |adultTravellerDetails index|}} {{my-s3-uploader class='uploader-button' onClick=(action 'updateIdStatus' index 'available')}} <div class="mdl-cell mdl-cell-6-col "> {{#if (eq adultTravellerDetails.id_update_status 'available')}} <p>UPDATE ID Proof</p> {{/if}} {{#if (eq adultTravellerDetails.id_update_status 'never_added')}} <p>ADD ID Proof</p> {{/if}} </div> {{/each}}
Key Takeaways
- Avoid modifying plain JS objects/arrays directly if you need Ember to update the template.
- Always use Ember's tracked system (Octane) or
Ember.Array/Ember.Objectwithget()/set()(older versions) for reactive data. - When fetching data from an API, convert it to Ember-trackable structures immediately after receiving it.
内容的提问来源于stack exchange,提问作者krishna murari

