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

Ember.js合并数据存储中两个对象为字符串的问题咨询

问题根源与解决方案

首先得给你点破核心问题:你现在的url和nickname变量其实不是字符串,而是Promise对象!Ember Data的store.find()方法是异步的,它返回的是一个Promise,只有当异步请求完成后,then回调里才能拿到真实的字符串值。

为什么会出现[Object object]和弹窗顺序混乱?

  • 直接把两个Promise对象相加,JavaScript会把它们转换成[object Promise]的字符串形式,所以你看到的是[Object object], [Object object]。
  • Promise的回调是异步执行的,你后面的alert(this.get('testFillSelect'))会在两个find的异步请求完成前就执行,所以先弹出了错误的合并结果,之后才会弹出then回调里的正确值。

解决方法:用RSVP.all等待所有异步请求完成

Ember内置了RSVP库来处理异步流程,我们可以用RSVP.all来等待两个Promise都成功resolve,再进行合并赋值:

preSelect: function (orgSiteId, orgId) { 
  'use strict'; 
  // 把两个异步请求的Promise单独存起来
  const urlPromise = this.get('store').find('orgSite', orgSiteId).then(orgSites => {
    return orgSites.get('url');
  });
  const nicknamePromise = this.get('store').find('org', orgId).then(orgs => {
    return orgs.get('nickname');
  });

  // 等待两个Promise都完成后再处理
  Ember.RSVP.all([nicknamePromise, urlPromise]).then(results => {
    const [nickname, url] = results;
    this.set('testFillSelect', `${nickname}, ${url}`);
    alert(this.get('testFillSelect')); // 现在会弹出正确的合并值
  });
}

关于计算属性/观察者的补充

如果你的testFillSelect需要随着orgSiteId或orgId的变化自动更新,那用计算属性会更符合Ember的设计思路。比如:

testFillSelect: Ember.computed('orgSiteId', 'orgId', function() {
  const orgSiteId = this.get('orgSiteId');
  const orgId = this.get('orgId');
  if (!orgSiteId || !orgId) return '';

  return Ember.RSVP.all([
    this.get('store').find('org', orgId).then(o => o.get('nickname')),
    this.get('store').find('orgSite', orgSiteId).then(os => os.get('url'))
  ]).then(([nickname, url]) => `${nickname}, ${url}`);
})

这种情况下,计算属性会在orgSiteId或orgId变化时自动重新计算,返回一个Promise,你可以在模板里用{{await testFillSelect}}(Ember 3.16+支持)来渲染结果,或者在代码里用then处理。

至于观察者,Ember官方现在更推荐用计算属性或追踪属性(@tracked,Ember Octane+)来替代观察者,因为观察者容易引发不必要的重计算和时序问题,所以优先考虑上面的方案就好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 12:37:52