Ember.js: Parameter Kueri Setel Ulang ke Nilai Default pada Render Awal Jika transisiTo dipanggil di beforeModel

Dibuat pada 21 Agu 2015  ·  48Komentar  ·  Sumber: emberjs/ember.js

Semoga judul dan bin JS ini mengatakan itu semua. TL; DR; adalah jika Anda memanggil transitionTo di beforeModel pada pemuatan awal (menekan tombol segarkan) parameter kueri akan disetel ulang ke status default di sana.

http://emberjs.jsbin.com/kicoro/1#

Bug Query Params

Komentar yang paling membantu

Juga melihat kesalahan ini di 2.14.

Semua 48 komentar

@raytiley Saya ingin tahu apakah ini adalah bug yang ada di 1.13 dan 2.0. Juga apakah contoh ini berfungsi pada versi Ember sebelumnya, yaitu 1.12?

@raytiley - Apakah menurut Anda ini terkait dengan https://github.com/emberjs/ember.js/issues/12107 (masalah root bijaksana)?

@rwjblue Mungkin sama saja, saya benar-benar perlu menggali sedikit lebih dalam untuk memahami di mana perilaku yang diinginkan harus terjadi. Masalah yang mendasarinya adalah bahwa qpMeta untuk setiap penangan belum diperbarui sebelum transisi baru dimulai. Ini terjadi dalam peristiwa finalizeQueryParamChange (https://github.com/emberjs/ember.js/blob/c9bbfb6081e6c145132addda84ed385b940979ff/packages/ember-routing/lib/system/route.js#L762) yang dipicu oleh router.

Pemahaman dasar saya tanpa menulis tes adalah ini. Anda awalnya memasukkan rute dengan url dengan parameter kueri ... ini membuat transisi baru, tetapi tidak pernah memanggil finalizeQueryParamChange karena itu terganggu oleh panggilan transitionTo di salah satu kait rute. Transisi baru ini mempersiapkan queryParams (https://github.com/emberjs/ember.js/blob/master/packages/ember-routing/lib/system/router.js#L603) tetapi karena qpMeta tidak pernah diperbarui oleh transisi asli menggunakan semua nilai default. Oleh karena itu, Anda terjebak dengan nilai default Anda :(

@pixelhandler Saya belum diuji versi lain, tapi saya tidak berpikir daerah ini kode telah berubah drastis, kecuali untuk @trek 's pekerjaan baru pada bergerak queryParam config ke router. Saya tidak percaya itu sudah mendarat, tapi mungkin tempat yang bagus untuk mengubah perilaku ini.

Idealnya saya pikir kita perlu menyelesaikan dan queryParam perubahan untuk transisi saat ini ketika memanggil transitionTo selama transisi aktif. Karena Anda bisa meneruskan queryParams ke transitionTo itu masih memberikan transisi baru cara untuk menimpa setiap perubahan queryParam dari panggilan transisi sebelumnya.

Bagi siapa pun yang mengikuti, sebagai solusi, saya dapat menjadwalkan transisiTo ke loop yang dijalankan di afterRender untuk mempertahankan queryParams saya. Anda mendapatkan kilatan yang mengganggu dari rute yang tidak diinginkan, tetapi lebih baik daripada kehilangan semua status masuk. Saya hanya memiliki ini di beberapa tempat di aplikasi saya, jadi ini bukan prioritas besar bagi saya untuk segera memperbaikinya, hanya ingin melaporkannya.

+1

@raytiley Saya mencoba solusi Anda tetapi queryParams saya masih dilucuti seperti:

Ember.run.scheduleOnce('afterRender', this, function() {
    this.replaceWith('campaign.show.onestep', { queryParams });
});

Itu sintaks yang benar, ya?

@noslouch Anda juga dapat mencoba antrian routerTransitions .

Saya tidak memiliki masalah persis ini, tetapi saya memiliki masalah dengan transitionTo({queryParams: { foo: 'bar' }}); di dalam beforeModel pada pemuatan awal. Saya baru saja mulai mendapatkan kesalahan di 2.1, itu baik-baik saja di 2.0. Entah bagaimana, params pertanyaan saya yang bertahan dan berperilaku aplikasi seperti yang diharapkan, hal yang hanya aneh adalah kesalahan ini.

Dari phantom:

TypeError: undefined is not an object (evaluating 'handlerInfos[handlerInfos.length - 1].name')

Dari chrome:

TypeError: Cannot read property 'name' of undefined
    at _emberRuntimeSystemObject.default.extend.actions.finalizeQueryParamChange (ember.debug.js:25996)
    at Object.triggerEvent (ember.debug.js:28253)
    at Object.trigger (ember.debug.js:50891)
    at finalizeQueryParamChange (ember.debug.js:50040)
    at Object.Router.queryParamsTransition (ember.debug.js:49418)
    at Object.getTransitionByIntent (ember.debug.js:49331)
    at Object.Router.transitionByIntent (ember.debug.js:49436)
    at doTransition (ember.debug.js:50008)
    at Object.Router.transitionTo (ember.debug.js:49505)
    at _emberRuntimeSystemObject.default.extend._doTransition (ember.debug.js:27978)

@kmiyashiro +1, saya mengalami masalah yang persis sama setelah meningkatkan ke 2.1.0

TypeError: Cannot read property 'name' of undefined
    at _emberRuntimeSystemObject.default.extend.actions.finalizeQueryParamChange (ember.debug.js:25996)
    at Object.triggerEvent (ember.debug.js:28253)
    at Object.trigger (ember.debug.js:50891)
    at finalizeQueryParamChange (ember.debug.js:50040)
    at Object.Router.queryParamsTransition (ember.debug.js:49418)
    at Object.getTransitionByIntent (ember.debug.js:49331)
    at Object.Router.transitionByIntent (ember.debug.js:49436)
    at doTransition (ember.debug.js:50008)
    at Object.Router.transitionTo (ember.debug.js:49505)
    at _emberRuntimeSystemObject.default.extend._doTransition (ember.debug.js:27978)

Ini baru saja menggigit saya juga, jika saya menambahkan ini ke rute yang sama sekali tidak terkait

import Ember from 'ember';

export default Ember.Route.extend({
  beforeModel: function() {
    this.transitionTo('works');
  }
});

Kemudian parameter kueri saya tampaknya dilucuti dan saya mendapatkan kesalahan ini ...

TypeError: Cannot read property 'name' of undefined
    at _emberRuntimeSystemObject.default.extend.actions.finalizeQueryParamChange (ember.debug.js:25680)
    at Object.triggerEvent (ember.debug.js:27911)
    at Object.trigger (ember.debug.js:52341)
    at finalizeQueryParamChange (ember.debug.js:51490)
    at Object.Router.queryParamsTransition (ember.debug.js:50868)
    at Object.getTransitionByIntent (ember.debug.js:50781)
    at Object.Router.transitionByIntent (ember.debug.js:50886)
    at doTransition (ember.debug.js:51458)
    at Object.Router.transitionTo (ember.debug.js:50955)
    at _emberRuntimeSystemObject.default.extend._doTransition (ember.debug.js:27636)

Saya menggunakan Ember: 2.3.0-canary+3486f33c

Terima kasih

Terjadi di [email protected] untuk saya.

Terjadi di sini juga ... [email protected]

Saya dengan @kmiyashiro , semuanya tampaknya berfungsi seperti yang diharapkan ... tetapi saya masih mendapatkan kesalahan di konsol. Saya dapat dengan mudah membuatnya kembali dalam sekejap. Cukup muat yang berikut dengan konsol terbuka. Anda bisa melihat kesalahan di ember 2.1 dan 2.2, sepertinya tidak muncul di 2.0.

https://ember-twiddle.com/86849f6610f3a68a9840?route=%2F%3Ftest%3Dfoo

Berikut ini solusi yang dapat Anda gunakan untuk memicu transisi sementara bug ini tetap tidak terselesaikan.

let RedirectAfterDidTransition = Ember.Mixin.create({
  redirectAfterDidTransition(...args) {
    this.router.one('didTransition', ()=>{
      this.router.transitionTo(...args);
    });
  }
});

export default Route.extend(RedirectAfterDidTransition, {
  afterModel() {
    this.redirectAfterDidTransition('index');
  }
});

Saya mengkloning Twiddle di atas dan menambahkan contoh https://ember-twiddle.com/2d49a9d1aa3ddaff6ef5?numColumns=1&route=%2F%3Ftest%3Dfoo

Catatan: ini akan menunggu transisi selesai sebelum melakukan pengalihan.

Ini adalah versi yang lebih sederhana yang tampaknya berfungsi dengan baik di kode saya

import Ember from 'ember';

// This mixin provides `abortAndTransitionTo` method that'll abort the current
// transition and transition to specified parameters.
// It takes same arguments as Route#transitionTo
// it's necessary because of https://github.com/emberjs/ember.js/issues/12169
let AbortAndTransitionTo = Ember.Mixin.create({
  abortAndTransitionTo(...args) {
    this.router.router.activeTransition.abort();
    this.router.transitionTo(...args);
  }
});

export default Route.extend(AbortAndTransitionTo, {
  afterModel() {
    this.abortAndTransitionTo('index');
  }
});

@taras bukankah ini menyia-nyiakan pengambilan karena itu setelah model?

Solusi saya hanyalah menangkap kesalahan dan mencatatnya karena saya tidak dapat menemukan efek samping apa pun.

beforeModel(transition) {
  this._super(...arguments);

  // Logic to set presetParams (dynamic initial params)

  this.transitionTo({ queryParams: presetParams })
    .catch(() => {
      log('Ember 2.1 query param issue: https://github.com/emberjs/ember.js/issues/12169');
    });
}

@kmiyashiro apa maksudmu: "buang-buang barang"? dan mengapa solusi Anda mencegah pengambilan terbuang percuma?

Saya berasumsi bahwa Anda mengambil (temukan / kueri) di model , jadi jika kueri Anda params refresh model, itu akan mengambil kembali model dengan parameter yang diperbarui. Jika Anda menggunakan transitionTo di dalam beforeModel , itu secara implisit membatalkan transisi aktif. Sayangnya, ada _banyak_ bug di sekitar transisi ke parameter kueri baru di salah satu kait ini:

https://github.com/emberjs/ember.js/issues/10577
https://github.com/emberjs/ember.js/issues/12102
https://github.com/emberjs/ember.js/issues/10945

Kami mungkin memiliki kasus penggunaan yang berbeda. Jika Anda ingin menjelajahinya lebih jauh, Anda dapat melakukan ping ke saya di Ember Community slack atau kami dapat memasangkan melalui http://j.mp/EmberSherpa

Mengalami masalah yang sama ini, meskipun saya tidak secara eksplisit memanggil transitionTo atau replaceWith , juga tidak ada rute yang melakukan apa pun dengan Ember-Data atau logika pengambilan model apa pun. Saya hanya menavigasi langsung ke rute dengan parameter kueri, yang memetakan ke properti boolean pada pengontrol rute. Ini hanya mulai terjadi ketika saya meningkatkan ke Ember 2.1+. Transisi tampaknya selesai dan semuanya berfungsi dengan baik, tetapi kesalahan dibuang ke konsol. Saya sudah mencoba beberapa solusi di atas, serta menimpa beberapa metode prototipe pribadi di Router, tetapi karena kesalahannya berasal dari router.js, yang disembunyikan dalam penutupan melalui Ember Router, saya tidak dapat menekan dengan andal kesalahannya.

Karena saya tidak dapat menahan kesalahan dengan andal, saya tidak dapat meningkatkan ke Ember 2.1 atau 2.2, karena kesalahan ini menyebabkan beberapa pengujian unit saya rusak, yang tidak disukai oleh sistem CI saya.

TypeError: Cannot read property 'name' of undefined
    at _emberRuntimeSystemObject.default.extend.actions.finalizeQueryParamChange (ember.debug.js:25264)
    at Object.triggerEvent (ember.debug.js:27476)
    at Object.trigger (ember.debug.js:51925)
    at finalizeQueryParamChange (ember.debug.js:51074)
    at Object.Router.queryParamsTransition (ember.debug.js:50452)
    at Object.getTransitionByIntent (ember.debug.js:50365)
    at Object.Router.transitionByIntent (ember.debug.js:50470)
    at doTransition (ember.debug.js:51042)
    at Object.Router.transitionTo (ember.debug.js:50539)
    at _emberRuntimeSystemObject.default.extend._doTransition (ember.debug.js:27201)

Saya bisa menekan kesalahan dengan menambal monyet Router:

export default Ember.Router.extend({
    _isRouterPatched: false,

    // monkey-patch the Ember.Router to suppress the error thrown by this bug:
    // https://github.com/emberjs/ember.js/issues/12169
    startRouting() {
        let result = this._super.apply(this, arguments);

        if (!this.get('_isRouterPatched')) {
            let _proto = Object.getPrototypeOf(this.router),
                _original = _proto.queryParamsTransition;

            _proto.queryParamsTransition = function () {
                try {
                    return _original.apply(this, arguments);
                } catch (e) {
                    console.warn(
                        'Ember 2.1 queryParams bug:',
                        'https://github.com/emberjs/ember.js/issues/12169',
                        e
                    );
                }
            };

            this.set('_isRouterPatched', true);
        }

        return result;
    }
});

Terjadi pada saya di Ember 2.2.2. Saya menangkap dan mencatat kesalahan karena tidak ada efek samping.

Ini mungkin bukan solusi yang paling elegan, tetapi ini sepertinya berhasil pada Ember 1.13:

// app/instance-initializers/global-query-params.js

import Ember from 'ember';
import _ from 'lodash';

const RouteSupport = Ember.Mixin.create({
  transitionTo: superWithGlobalQueryParams,
  replaceWith: superWithGlobalQueryParams
});

function getQueryParams(...names) {
  return names.reduce(function(result, name) {
    const regex = new RegExp(`[?&]${name}=([^?&]+)`);
    const md = regex.exec(window.location.search || '');
    if (md) { result[name] = md[1]; }
    return result;
  }, {});
}

function superWithGlobalQueryParams(...args) {
  const globalQueryParams = getQueryParams('tango-version');

  if (args.length === 1) {
    // transitionTo('some.route');
    args.push({ queryParams: globalQueryParams });
  } else if (args.length === 2 && args[1].queryParams) {
    // transitionTo('some.route', { queryParams: { ... } });
    args[1].queryParams = _.extend({}, globalQueryParams, args[1].queryParams);
  } else if (args.length === 2) {
    // transitionTo('some.route', someModel);
    args.push({ queryParams: globalQueryParams });
  } else {
    // transitionTo('some.route', someModel, { queryParams: { ... } });
    args[2].queryParams = _.extend({}, globalQueryParams, args[2].queryParams);
  }

  return this._super(...args);
}

export default {
  name: 'global-query-params',

  initialize() {
    Ember.Route.reopen(RouteSupport);
  }
};

Jika Anda tidak ingin mempertahankan daftar parameter kueri yang diizinkan di sana, Anda mungkin dapat mengurai semuanya menggunakan sesuatu seperti ini .

Hal yang sama terjadi tanpa memanggil transisiTo secara langsung

beforeModel(transition) {
  let token = transition.queryParams.token;
  return this.get('session').authenticate('authenticator:custom', token).then(...).catch(...);
}

ember-simple-auth mencoba beralih ke '/' jika auth berhasil.

Ember 2.3.0.beta2

Terjadi pada saya juga. Menggunakan solusi abortAndTransitionTo @taras .

Ember: 2.2.0

Saya melihat varian pada bug ini di kode saya.

Kesalahan yang saya lihat terjadi saat saya memuat ulang halaman yang memiliki parameter kueri. Halaman itu sendiri berada dalam rute bersarang - metode setupController dalam rute induk dan kakek-nenek memanggil transitionTo untuk menuju ke rute yang benar. Transisi perutean berfungsi dengan baik saat mengunjungi URL root aplikasi - transisi terjadi, dan URL disetel dengan benar termasuk parameter kueri, dan tidak ada kesalahan yang terjadi.

Kesalahan spesifik yang saya lihat adalah:

TypeError: Cannot set property '_qpDelegate' of undefined
    at _emberRuntimeSystemObject.default.extend.actions.finalizeQueryParamChange (ember.debug.js:26398)
    at Object.triggerEvent (ember.debug.js:28636)
    at Object.trigger (ember.debug.js:53210)
    at finalizeQueryParamChange (ember.debug.js:52359)
    at Object.Router.queryParamsTransition (ember.debug.js:51737)
    at Object.getTransitionByIntent (ember.debug.js:51650)
    at Object.Router.transitionByIntent (ember.debug.js:51755)
    at doTransition (ember.debug.js:52327)
    at Object.Router.transitionTo (ember.debug.js:51824)
    at _emberRuntimeSystemObject.default.extend._doTransition (ember.debug.js:28347)

Objek undefined dimaksud adalah controller (diambil dari route.controller dalam lingkaran yang melebihi qpMeta.qps di dalam finalizeQueryParamChange .

Ketika saya memasukkan breakpoint, saya dapat melihat bahwa finalizeQueryParamChange dipanggil dua kali. Hanya pada saat pertama kali objek controller menjadi tidak terdefinisi.

Pengecualian yang diberikan tampaknya tidak berbahaya, jadi bagi saya patch @rzurad berfungsi untuk mengatasi masalah ini.

Ember: 2.4.2

Perbaikan disertakan dalam v2.4.4.

Hmm, setelah mengupgrade "ember" ke "2.4.4" di bower.json saya, dan menghapus solusi taras AbortAndTransitionTo , saya masih memiliki kesalahan TypeError: Cannot read property 'name' of undefined . Stacktrace yang sama dengan komentar ini .

@ John-kurkowski dapatkah Anda mencoba untuk membuat reproduksi ember-twiddle / jsbin sederhana bersama-sama? Sekarang semua kode ini segar dalam pikiran saya, saya mungkin bisa mengetahuinya cukup cepat dengan reproduksi.

@ john-kurkowski Saya pikir ini akan memperbaiki kesalahan itu: https://github.com/emberjs/ember.js/pull/13273

Berharap untuk menyelesaikan pengujian besok dan kemudian saya akan mengganggu @rwjblue untuk bergabung :)

Masih mengalami masalah pada Ember 2.6.0

Hmm, saya menggunakan 2.4.6 dan masih mendapatkan masalah.

Luar biasa terima kasih @Unnumbered

Masih terjadi pada saya di 2.7.0.

Masih terjadi pada saya di 2.9.0. afterModel() transitionTo(another route) berfungsi dengan baik, tetapi transitionTo(this-route-with-different-query-params) gagal dengan TypeError: Cannot read property 'name' of undefined . Menggunakan metode redirect() menghasilkan hasil yang sama, seperti halnya replaceWith() menggantikan transitionTo() . Untuk membuatnya berfungsi, saya harus mengatur rute queryParams hash sebagai berikut:

queryParams: {
  category: {
    refreshModel: true
  }
}

tapi itu menyakitkan karena saya sebenarnya tidak ingin menyegarkan model. (model yang saya miliki baik-baik saja!) Tetapi dengan perubahan ini semua variasi kode di atas ( redirect() dan replaceWith() ) berfungsi dengan baik, meskipun replaceWith() tidak benar-benar menggantikan item sejarah.

Masih terjadi pada saya di 2.10.2 tetapi dengan jejak tumpukan yang sedikit berbeda:

TypeError: Cannot read property 'name' of undefined
    at Class._queryParamsFor (ember.debug.js:27449)
    at Class.finalizeQueryParamChange (ember.debug.js:25269)
    at Router.triggerEvent (ember.debug.js:27862)
    at trigger (ember.debug.js:55572)
    at finalizeQueryParamChange (ember.debug.js:57560)
    at Router.queryParamsTransition (ember.debug.js:56907)
    at Router.getTransitionByIntent (ember.debug.js:56816)
    at Router.transitionByIntent (ember.debug.js:56925)
    at doTransition (ember.debug.js:57527)
    at Router.transitionTo (ember.debug.js:57001)

Saya kira masalah ini harus dibuka kembali.

Masalah yang sama di 2.10.0
afterModel(model) { if (model.get('length') === 0) { this.transitionTo('users', { queryParams: { page: 1 }}); } }

Saya melihat jejak tumpukan yang sama dengan @ slava-dzyba di 2.10.2 juga.

Melihat kesalahan yang sama di 2.12.1. Mencoba solusi di atas dan perbaikan yang diusulkan tetapi tidak berhasil.

Juga melihat kesalahan ini di 2.14.

Solusi saya untuk ini adalah dengan membatalkan transisi secara manual sebelum beralih ke rute lain.

  beforeModel(transition) {
    // For example, first time we transition
    if (transition.sequence === 0) {
      transition.abort();
     // replace with whatever route/query params work for you
      this.replaceWith('index');
    }
  }

Sepertinya bekerja pada versi Ember 2.18 dan 3.0. Semoga ini membantu.

Melihat masalah yang sama dengan 2.18 dan tumpukan dari @sdzyba

Saya sudah mencoba transition.abort() dari @jorblume tetapi tidak berhasil, eksekusi tampaknya berhenti dan tidak pernah mengeksekusi transitionTo

Masalah yang sama dengan 3.3 saat menggunakan transitionTo() di afterModel() , solusi saya:

            if (transaction.sequence === 0) {
                transaction.abort();                
                this.transitionTo('route', {queryParams: newQueryParams});    
            }

Hei!

Saya dapat mengonfirmasi bahwa solusi @jorblume berfungsi di Ember 2.18

Salam Hormat,
Daniel.

Saya menyelesaikannya dengan kembali tepat setelah this.transitionTo() dipanggil:

model(){
...
if(someCondition){
   return this.transitionTo({ queryParams: error.data.params });
}
...
}

Jika pernyataan return ada di baris di bawah this.transitionTo() , masalah tetap ada.
Ngomong-ngomong, saya tidak menggunakan transition.abort() sama sekali karena menghentikan transisi lain yang akan datang - aplikasi macet.

Saya mengalami kesalahan yang sama tetapi dalam kasus saya, saya harus mengganti penggunaan this.replaceWith('/'); dengan nama rute sebenarnya this.replaceWith('my.route') setelah menambahkan rute bersarang untuk rute X seperti:

this.route(..., { path: '/' }, function() {
   this.route(..., { path: '/' })
});

Setelah menambahkan rute bersarang dengan / aplikasi mulai mogok dengan kesalahan di atas evaluating 'handlerInfos[handlerInfos.length - 1].name' .

Ember.js v3.5.0 .

Ada pembaruan tentang ini? Belum bisa mendapatkan solusi apa pun untuk bekerja. Pada Ember v3.4.0

Apakah halaman ini membantu?
0 / 5 - 0 peringkat