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

Ember-selectize报错:"focused"被修改两次,新增项无法自动选中

解决Ember Selectize组件新增项无法自动选中且触发"focused"重复修改报错的问题

我之前在使用Ember Selectize组件时也踩过类似的坑,来帮你拆解下问题和解决办法:

问题根源分析

  1. 新增项无法自动选中:Selectize组件默认不会自动选中刚创建的新项,需要手动触发选中状态,但直接修改绑定的模型属性,容易和组件内部的状态更新逻辑冲突。
  2. "You modified 'focused' twice"报错:这是Ember RunLoop的检测机制在告警——同一个渲染周期内,focused属性被修改了两次:一次是组件内部处理输入/创建逻辑时自动修改,另一次是你通过设置模型触发的选中操作,两者撞在了同一个RunLoop周期里。

具体解决步骤

核心思路是避开组件内部的状态更新周期,用Selectize原生API手动控制选中状态,同时借助Ember的RunLoop调度确保操作时机正确:

1. 调整createItem Action逻辑

修改你的创建项方法,先把新项加入数据源,再延迟执行选中操作,避免和组件内部状态修改冲突:

import { run } from '@ember/runloop';
import $ from 'jquery';

// ... 其他代码 ...

actions: {
  createItem(item) {
    console.log("create ", item);
    // 1. 先把新项添加到数据源数组
    this.get('references').addObject(item);
    
    // 2. 获取Selectize组件的原生实例
    const selectizeEl = this.$('.selectize-control')[0];
    if (!selectizeEl?.selectize) return;
    const selectizeInstance = selectizeEl.selectize;

    // 3. 在RunLoop的afterRender阶段执行选中操作,避开组件内部的状态更新
    run.scheduleOnce('afterRender', this, () => {
      // 用项的唯一标识(比如id)选中新创建的项
      selectizeInstance.addItem(item.id);
      // 刷新选项列表确保新项正常显示
      selectizeInstance.refreshOptions();
    });
  }
}

2. 优化组件绑定(可选)

如果你的模板里绑定了value属性来控制选中状态,也可以在afterRender阶段同步更新这个值,但同样要放在延迟调度里:

{{! 模板中的Selectize组件调用 }}
{{selectize
  options=references
  create=true
  on-create=(action 'createItem')
  value=selectedReferenceId
}}
// 在createItem的afterRender回调里添加:
this.set('selectedReferenceId', item.id);

为什么这样能解决问题?

  • run.scheduleOnce('afterRender')确保选中操作在组件完成渲染、内部状态(包括focused)更新完成后再执行,从根源上避免了重复修改的冲突。
  • 直接调用Selectize的原生APIaddItem来控制选中状态,绕开了Ember数据绑定和组件内部状态的交叉冲突,操作更直接可靠。

内容的提问来源于stack exchange,提问作者The Old County

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:17:03