Ember.js: 在setupController中设置控制器属性不会更新查询参数

创建于 2014-08-21  ·  29评论  ·  资料来源: emberjs/ember.js

如果您将控制器定义为

App.IndexController = Ember.Controller.extend({
  queryParams: ['foo'],
  foo: ''
});

在Routes setupController中,您可以执行以下操作...

setupController: function(controller, model){
  controller.set('model', model);
  controller.set('foo', 'bar'); // <-- setting this should update the query param
}

网址中未设置查询参数。

您可以在这里看到一个工作箱: http :

Bug Inactive Query Params

最有用的评论

我也在Ember 2.11上看到了这个问题,试图清除控制器中的查询参数没有任何效果, @ barelyknown的变通方法可以使我获得大部分解决方法,但是我仍然会认为这是一个开放的错误。

所有29条评论

使用Ember.run.later进行了修复(以确保首先完全实现): http :

@machty-这里的预期行为是什么?

我以为我们对此进行了明确的测试。

我认为这是一个错误...我们对此进行了测试,但仅在transitionTo的情况下进行了测试,而不是在初始应用程序启动时进行。

工作: http

我为此错误添加了失败的测试https://github.com/emberjs/ember.js/pull/5473
会试图解决这个问题

我想我偶然发现了相关问题,所以不确定在GitHub中是否需要单独的票据。

export default Ember.Controller.extend({
    queryParams: ['modal'],
    modal: null,
    handleModal: function () {
        this.send('openModal', this.get('modal'));
    }.observes('modal')
});
export default Ember.Route.extend({
    actions: {
        openModal: function (name) {
            return this.render(name, {
                into: 'application',
                outlet: 'modal'
            });
        }
    }
});

这在启动时抛出Error while processing route: index Nothing handled the action 'openModal'. If you did handle the action, this error can be caused by returning true from an action handler in a controller, causing the action to bubble.所有情况下均有效

可以使用Ember.run.next进行修复

handleModal: function () {
    Ember.run.next(this, function () {
        this.send('openModal', this.get('modal'));
    });
}.observes('modal')

虽然感觉不对。

JSBins:
没有Ember.run.next会引发错误
使用Ember.run.next在控制台中打印“重新”

@ Igor10k我正在碰到这个完全相同的问题,模态和全部。 将其包装在Ember.run.next中可以修复它,但是我也感到不对。

谁能确认这仍然是1.8中的问题?

@wagenet是的,这在1.8中仍然是一个问题:
http://emberjs.jsbin.com/lezuhu/1/edit?html,js ,输出

和金丝雀:
http://emberjs.jsbin.com/doyohe/1/edit?html,js ,输出

@machty-有什么想法吗?

我认为使用1.8.1也是我的一个错误。 我想做的是每次特定的queryParam更改时在控制器上调用一个特殊方法。 我有一个看起来像这样的路由器。
有什么建议吗?

// ...snip...

// for pagination
queryParams: {
  offset: {
    refreshModel: true
  }
},

model: function(params) {
  // returns model
},

setupController: function(controller, model) {
  this._super(controller, model);
  controller.set('model', model);

  // Fetch results is a method that does a bunch work
  // sets up some filters, generates a promise, resolves that promise
  // and then sets some array data on the controller once promise resolves.
  // offset is a pagination feature which determines which specific results
  // are fetched. I would like to be able to call fetchResults everytime the
  // offset queryParam is changed. 
  Ember.run.later(function() {
    controller.sendAction('fetchResults');
  })
}

// ...snip...

@machty-关于从哪里开始挖掘的想法?

我有同样的问题。 控制器中的this.set()不会更新URL中的查询参数

App.SearchController = Ember.Controller.extend({
queryParams:['domain'],
域:null,

domainField:Ember.computed.oneWay('domain'),
动作:{
searchSubmit:function(){
this.set('domain',this.get('domainField')); //这会设置'domain'参数,但不会修改URL。 因此,App.SearchRoute中的模型永远不会像预期的那样被调用
}
},
});

App.SearchRoute = Ember.Route.extend({
queryParams:{
域:{
refreshModel:true //选择完全过渡
},

},
型号:function(params){
var domain = params.queryParams.domain;

  return $.getJSON('/search?domain=usv.com&name=').then(function(resp){
  console.log(resp);
  return resp.data;
});

},
动作:{
刷新:function(){
Ember.Logger.log('路由现在正在刷新...');
this.refresh();
}
},
});

您能否在此期间提供解决方法?

需要说明的是:我的代码中的this.set()将更改Class对象,但根本不会更改URL

这很古老,但似乎仍然有问题吗? 我无法弄清情况,但是当我尝试从控制器设置查询参数时,它不会定期传播到URL。 我可以检查控制器上属性的值,并且属性值已正确设置,但URL并未更改。 我尝试使用Ember.run.next无济于事。 !

也遇到这个问题

@rwjblue :对此有任何更新吗?

任何更新? 在这里,即使从控制器更改值,URL也会更新几毫秒,并且即使控制器中变量中有新值,URL也会恢复为旧值。

解决方法:

在控制器中,添加一个观察者,该观察者将在设置后的下一个运行循环中更改查询参数。 在此示例中,我想从URL中删除token查询参数,此方法效果很好。

import Ember from 'ember';

export default Ember.Controller.extend({
  queryParams: ['token'],

  token: null,

  unsetToken: Ember.observer('token', function() {
    if (this.get('token')) {
      Ember.run.next(this, function() {
        this.set('token', null);
      });
    }
  }),
});

今天,当我尝试在启动时从setupController设置查询参数时,就遇到了这种情况。 run.next似乎是一种解决方法,但我认为正确的解决方案是拥有2条路由,并且在启动时,第一条路由将使用查询参数值执行transitionTo第二条路由。

灰烬2.8

根据我们的分类政策,标记问题为无效。

我也在Ember 2.11上看到了这个问题,试图清除控制器中的查询参数没有任何效果, @ barelyknown的变通方法可以使我获得大部分解决方法,但是我仍然会认为这是一个开放的错误。

编辑:忽略所有这些爵士乐。 这里有一些错误/错误的信息, @ locks为我提供了一个更好的解决方案-使用查询参数代替动态段-紧接在下面。 它将查询参数绑定到具有阴影计算属性的普通属性,该阴影属性对get清理并设置(我以前的尝试涉及将查询参数绑定到经过清理并设置在set上的计算属性) 。 对不起,噪音!


更好的解决方案...

// app/router.js
Router.map(function() {
  this.route('shop');
});

// app/routes/shop.js
export default Ember.Route.extend({
  queryParams: {
    _selectedItemIndex: {
      replace: true
    }
  }
});

// app/controllers/shop.js
import computed from 'ember-macro-helpers/computed';

export default Ember.Controller.extend({
  cart: Ember.service.inject(),

  queryParams: {
    _selectedItemIndex: 'i'
  },

  _selectedItemIndex: 0,

  selectedItemIndex: computed('_selectedItemIndex', {
    get(index) {
      const itemsLength = this.get('cart.items.length');

      if (isNaN(index) || index < 0 || index >= itemsLength) {
        index = 0;
      }

      return this.set('_selectedItemIndex', index);
    },

    set(index) {
      return this.set('_selectedItemIndex', index);
    }
  })
});


原来的问题和解决方法...

我昨天失去了大部分时间,但这个问题仍然存在于2.14-beta中。 我的用例是清理查询参数以用作Ember.Array的索引。 如果格式不正确(例如NaN或字符串)和/或超出范围,则应使用默认索引,并更新URL以反映调整(以便响应将来点击的事件能够适当触发—我可以进一步解释)帮助我们证明这不仅是表面问题)。

我无法从setupController()设置属性,因为它不会更新URL(如本期所述)。 我不能使用Ember.run在下一个刻度中设置它,因为那样生效太晚了(即,无效索引已经用于访问数组)。 我无法设置一次,然后在下一个刻度中再次设置它以更新URL,因为没有属性更改(或者至少我怀疑这是它不起作用的原因)。

我不能在控制器中使用带有消毒设置程序的计算属性,因为您不能将查询参数绑定到计算属性。 我无法在普通属性上使用观察器,因为您无法设置要观察的属性。 由于上述问题,我无法在Ember.run中使用观察器。

由于#14606和相关问题,我无法从setupController()调用this.transitionTo({ queryParams: .. })setupController()调用this.transitionTo({ queryParams: .. }) beforeModel()挂钩或从setupController()调用this.transitionTo({ queryParams: .. }) controller.transitionToRoute({ queryParams: .. }) 。 我无法将refreshModeltrue的查询参数,因为model()挂钩中发生了其他事情,如果此查询参数发生更改,则不应重复。

显然,这里有痛苦的联系。 此问题(问题编号14606)和无法将查询参数绑定到计算属性的局限性共同造成了一个整洁,令人沮丧的小陷阱。

这是我的解决方法:我创建了一个嵌套的“选择”路由,该路由仅采用查询参数(或(如下面的代码中的那样)一个动态段),对其进行清理,并在其父控制器上设置属性。 如果清理后的索引超出范围,它将转换为嵌套索引路由,而嵌套索引路由又转换回具有默认索引的嵌套选择路由。 嵌套路由没有模板或控制器,父路由没有出口。 它们仅存在以解决此路由问题。

// app/router.js
Router.map(function() {
  this.route('shop', function() {
    this.route('index', { path: '/' });
    this.route('select', { path: '/:index' });
  });
});

// app/routes/shop.js
export default Ember.Route.extend({
  setupController(controller, model) {
    this._super(...arguments);

    // some logic to set up the cart service
  },

  model() {
    // fetch products to shop
  }
});

// app/controllers/shop.js
export default Ember.Controller.extend({
  cart: Ember.service.inject(),

  selectedItemIndex: 0,

  actions: {
    selectItem(index) {
      return this.replaceRoute('shop.select', index);
    }
  }
});

// app/routes/shop/index.js
export default Ember.Route.extend({
  beforeModel() {
    return this.replaceWith('shop.select', 0);
  }
});

// app/routes/shop/select.js
export default Ember.Route.extend({
  setupController(_, { index }) {
    this._super(...arguments);

    const
      parentController = this.controllerFor('shop'),
      itemsLength = parentController.get('cart.items.length');

    index = parseInt(index, 10);
    if (Number.isNaN(index) || index < 0 || index >= itemsLength) {
      return this.replaceWith('shop.index');
    }

    parentController.set('selectedItemIndex', index);
  },

  model: _ => _
});

@mwpastore感谢您的更新,我们将关闭此问题。 周末愉快!

@locks如果需要,请重新打开一个文档问题,以在setupController上对此加以注意(例如,请参阅@mwpastore下拉列表中的

@mwpastore听起来我们可以在https://discuss.emberjs.com/上的论坛上跟进您的解决方案

等等,这个问题已通过替代解决方案解决了它报告的错误,并且该解决方案涉及在计算的吸气剂中设置属性?

我很好奇是否有更新。

我在路线的setupController使用Ember.run.next setupController

此页面是否有帮助?
0 / 5 - 0 等级