You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌套JSON数据填充表单与网格的两类技术问题求助

Two Data Binding Issues with Nested JSON Forms & Grids: Cancel Button Failure + Combobox Glitch

Context

You're working with nested JSON data (root AqiConfig with Type (unique) and Pollutants (hasMany) associations) to populate a form and grids. When a row in aqiGrid is clicked, subsequent components are populated. You've hit two tricky issues:


Problem 1: Cancel Button Fails After Editing Type Combobox in aqiForm

When you edit the Label field and click Cancel, changes revert correctly—but modifying the Type combobox breaks the Cancel functionality entirely.

Why This Happens

This is almost always tied to how your Type combobox interacts with the nested Type association in your AqiConfig model. Common root causes:

  • The combobox isn't properly linked to the model's Type reference (e.g., mismatched valueField/displayField settings).
  • Your Cancel logic only rolls back changes on the root AqiConfig model, not the associated Type model.
  • Custom code in the combobox's select/change events accidentally commits changes or bypasses the model's dirty state tracking.

Fixes to Try

  1. Validate Combobox Binding
    Double-check your combobox config to ensure it's correctly tied to the nested Type model:

    {
      xtype: 'combobox',
      fieldLabel: 'Type',
      valueField: 'Id', // Matches Type model's unique ID field
      displayField: 'Label', // Matches Type model's display field
      bind: '{aqiConfig.Type.Id}', // Explicitly bind to the nested Type's ID
      store: typeOptionsStore, // Your preloaded Type options store
      forceSelection: true
    }
    

    This ensures selecting a Type updates the nested model correctly and marks it as dirty for rollback.

  2. Update Cancel Logic to Handle Associations
    If Type is a hasOne association on AqiConfig, make sure your Cancel handler rolls back changes on both the root model and the associated Type:

    cancelHandler: function() {
      const aqiConfig = this.getViewModel().get('aqiConfig');
      // Roll back root model changes
      aqiConfig.rejectChanges();
      // Roll back associated Type model if it exists
      if (aqiConfig.Type) {
        aqiConfig.Type.rejectChanges();
      }
      // Refresh the form to sync view with the rolled-back model
      this.up('form').getForm().loadRecord(aqiConfig);
    }
    

    Alternatively, set cascadeReject: true in your AqiConfig model's Type association config to auto-rollback nested changes when the root model rejects changes.

  3. Check for Accidental Commit Logic
    Scan the combobox's select or change events for any code that calls commitChanges() on the model—this would lock in changes before you can cancel them.


Problem 2: Physical Combobox in aqiPollutantGrid Glitches on Edit

When editing the physical value in the grid's last column:

  • The current value disappears immediately when editing starts
  • Selecting a new value results in the first option being displayed instead
  • Calling rejectChanges() fixes the Optional field but breaks the combobox

Why This Happens

This is typically a mismatch between the combobox's configuration and the grid row model's physical field. Common issues:

  • Type mismatch between the combobox's valueField and the model's physical field (e.g., model stores a string ID, combobox uses numeric values)
  • The cell editor combobox isn't properly syncing with the model during edit/cancel
  • rejectChanges() rolls back the model but doesn't trigger a grid refresh, leaving the combobox in an inconsistent state

Fixes to Try

  1. Align Combobox and Model Field Types
    Ensure the combobox's valueField matches the data type of your Pollutants model's physical field exactly. For example, if your model stores physical as a string ID, the combobox's valueField should point to the string ID in your physical options store.

  2. Improve Cell Editor Configuration
    Tweak your grid column's editor to enforce valid selections and sync properly:

    {
      text: 'Physical',
      dataIndex: 'physical',
      editor: {
        xtype: 'combobox',
        store: physicalOptionsStore,
        valueField: 'id', // Match your physical option's unique ID field
        displayField: 'label', // Match your physical option's display field
        forceSelection: true,
        queryMode: 'local',
        triggerAction: 'all'
      }
    }
    

    forceSelection: true prevents invalid values, and queryMode: 'local' ensures the dropdown loads correctly without unnecessary remote calls.

  3. Handle Canceled Edits Precisely
    Instead of relying on rejectChanges() (which rolls back all fields), save the original physical value before editing and restore it if the user cancels. Use the grid's beforeedit and canceledit events:

    listeners: {
      beforeedit: function(editor, context) {
        // Save original physical value for the row
        context.record.originalPhysical = context.record.get('physical');
      },
      canceledit: function(editor, context) {
        // Restore original value
        context.record.set('physical', context.record.originalPhysical);
        // Refresh the row to update the combobox display
        context.grid.getView().refreshRow(context.record);
        // Clean up the temporary property
        delete context.record.originalPhysical;
      }
    }
    

    This targets only the physical field, avoiding unintended side effects on other fields like Optional.

  4. Fix rejectChanges() Glitch
    If you still want to use rejectChanges(), add a grid refresh after calling it to sync the view with the rolled-back model:

    // In your cancel logic
    record.rejectChanges();
    grid.getView().refreshRow(record);
    

    This ensures the combobox re-renders with the original model value, eliminating the error.


内容的提问来源于stack exchange,提问作者mpe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:29:23