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
}

クエリパラメータがURLに設定されません。

ここで作業ビンを見ることができます: http

Bug Inactive Query Params

最も参考になるコメント

私もEmber2.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を使用すると、コンソールで「redered」が出力されます

@ Igor10k私はこれとまったく同じ問題、モーダル、そしてすべてに

これが1.8でもまだ問題であることを誰かが確認できますか?

@ 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:['ドメイン']、
ドメイン: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から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つのルートを用意し、起動時に最初のルートがクエリパラメータ値を使用してtransitionTo2番目のルートを実行することだと思います。

残り火2.8

トリアージポリシーに従って、問題を非アクティブとしてマークします。

私もEmber2.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-ベータでまだ残っています。 私のユースケースは、Ember.Arrayへのインデックスとして使用するクエリパラメーターをサニタイズすることです。 不正な形式(NaNや文字列など)や範囲外の場合は、デフォルトのインデックスを使用し、調整を反映するようにURLを更新する必要があります(今後のクリックに応じたイベントが適切にトリガーされるように、これについてさらに説明できます。これが単なる見た目の問題ではないことを主張するのに役立ちます)。

URLを更新しないため、 setupController()からプロパティを設定できません(この問題で説明されています)。 Ember.runを使用して次のティックに設定するのは遅すぎます(つまり、無効なインデックスが配列へのアクセスにすでに使用されているため)。 プロパティの変更がないため、一度設定してから次のティックで再度設定してURLを更新することはできません(または、少なくともそれが機能しない理由だと思います)。

クエリパラメーターを計算プロパティにバインドできないため、コントローラーのサニタイズセッターで計算プロパティを使用することはできません。 監視しているプロパティを設定できないため、通常のプロパティでオブザーバーを使用できません。 上記の問題により、Ember.runでオブザーバーを使用できません。

私は呼び出すことはできませんthis.transitionTo({ queryParams: .. })からsetupController()またはbeforeModel()フックまたはcontroller.transitionToRoute({ queryParams: .. })からsetupController() #14606と関連する問題に起因します。 model()フックで他のことが発生しているため、クエリパラメータにrefreshModeltrueに設定できません。このクエリパラメータが変更された場合は繰り返さないでください。

明らかに、ここには痛みのつながりがあります。 この問題、問題#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を使用しています

このページは役に立ちましたか?
0 / 5 - 0 評価