Angular-google-maps: Cluster melanggar aplikasi universal

Dibuat pada 22 Nov 2017  ·  30Komentar  ·  Sumber: SebastianM/angular-google-maps

Deskripsi masalah

Mengimpor modul cluster saja sudah merusak aplikasi.

Langkah-langkah untuk mereproduksi dan demo minimal masalah

Saya memiliki peta di mana semua penandanya berada di bawah sebuah cluster. Peta dibungkus ke dalam kondisi sehingga hanya dirender di klien (bukan di server) karena ada masalah yang diketahui. Namun, itu masih merusak rendering sisi server karena mencoba mengakses window di beberapa titik. Ini mungkin terjadi selama inisialisasi modul, karena komponen itu sendiri tidak pernah dipakai.

Perilaku saat ini

Aplikasi yang menggunakan cluster tidak dapat digunakan di aplikasi sisi server.

Perilaku yang diharapkan/diinginkan

Aplikasi tidak boleh rusak.

versi angular & angular-google-maps

  • @angular/* pada 5.0.0
  • @agm/core pada 1.0.0-beta.2

Informasi lainnya

Saya mencari ATM solusi tetapi, tentu saja, akan lebih baik jika pengguna yang memiliki aplikasi Universal tidak perlu melakukan apa pun. Setidaknya kita harus membungkus semua kode dengan isPlatformBrowser dan hanya mencantumkannya sebagai peringatan untuk saat ini, sampai kita mengetahui cara membuat peta di server, jika memungkinkan.

stale

Komentar yang paling membantu

Saya memotong proyek js-marker-clusterer dan melakukan perbaikan. Ini mencegah inisialisasi MarkerClusterer ketika jendela tidak ditentukan (pada rendering sisi server). Jadi penanda clusterer berfungsi dengan benar dalam kedua kasus sekarang.

Ini diterbitkan di npm. https://www.npmjs.com/package/js-marker-clusterer-universal

Ketergantungan js-marker-clusterer harus diganti dengan js-marker-clusterer-universal agar berlaku.

Semua 30 komentar

@lazarljubenovic ya pembungkus akan menjadi solusi yang baik untuk saat ini.
cc @jigfox

Saya akan melihat ke dalam ini

@lazarljubenovic Saya tidak punya pengalaman dengan aplikasi universal, dan saya tidak yakin bagaimana menggunakan isPlatformBrowser dengan benar, bisakah Anda memberi saya beberapa petunjuk?

@jigfox Tentu! Anda dapat menyuntikkan token PLATFORM_ID ke dalam komponen, seperti:

constructor(@Inject(PLATFORM_ID) private platformId: any) {
}

Kemudian Anda dapat menggunakan fungsi Angular seperti isPlatformBrowser atau isPlatformServer untuk menjalankan bagian kode tertentu secara kondisional hanya pada platform tertentu.

constructor(@Inject(PLATFORM_ID) private platformId: any) {
  if (isPlatformBrowser(this.platformId)) {
    console.log('This code runs only in browser')
  }
}

Saya tidak yakin di mana harus meletakkan ini, panggilan ke window ada dalam kode yang disediakan oleh js-marker-clusterer:

markerclusterer.js#L698 dan markerclusterer.js#L1270 jadi cluster-manager.ts#L3 harus dibungkus?

Mungkin perlu menonaktifkan seluruh plugin cluster pada bukan platform Browser? Tapi mungkin markerclusterer.js menulis ulang bisa membantu, karena bisa ditulis ulang tanpa referensi window

Ah, itu kode dari lib pihak ketiga. Astaga. Saya ingin tahu apakah hanya mengatakan sesuatu seperti ini akan membantu:

const oldWindow = window || {}
window = {
  setTimeout: oldWindow.setTimeout
}
import 'js-marker-clusterer'
window = oldWindow

Tapi saya pikir server itu akan rusak dari hanya menemukan window saat mengeksekusi kode, karena variabelnya belum dipakai, jadi itu mungkin akan rusak juga, meskipun itu ide yang bagus.

Bisakah kita melakukan import tidak di awal file, tetapi di dalam komponen? Apa yang akan dilakukan?

Omong-omong, dikatakan di Google Map repo ini:

Harap dicatat: Repositori ini saat ini tidak dikelola, dan disimpan untuk tujuan historis saja.

Jadi bagaimana kalau kita membayarnya sendiri? Karena ini adalah repo historis, itu tidak akan pernah berubah yang berarti tidak ada masalah hanya dengan menggunakan versi tweak kami sendiri yang tidak menggunakan window sama sekali?

Oh, dan tentang ini:

Tapi saya pikir server itu akan rusak dari hanya menemukan jendela saat mengeksekusi kode, karena variabelnya belum dipakai, jadi itu mungkin akan rusak juga, meskipun itu ide yang bagus.

Ini terlihat sangat mendasar tetapi saya baru mempelajari ini beberapa hari yang lalu:

Jika Anda mencoba melakukan if (window == null) atau yang serupa dan window tidak ada sebagai variabel dalam cakupan yang dikunjungi, kode akan terputus dengan ReferenceError . Namun, jika Anda melakukannya if (typeof window == 'undefined' ), itu akan berfungsi dengan baik dan memberikan hasil yang diharapkan bahkan jika window tidak pernah dideklarasikan (yang merupakan masalah kami di server).

Saya kira saya bisa mencoba bermain-main dan membuat versi repo Cluster kami sendiri dan melihat apa yang bisa dilakukan dengan menggunakan ini.

Saya mencoba memperbaikinya menggunakan pendekatan berikut:

http://ideasintosoftware.com/typescript-conditional-imports/

Tetapi saya tidak beruntung, karena kompiler AOT akan mulai mengeluh bahwa arahan tidak lagi dapat ditemukan.

Ya, kompiler AOT secara statis menganalisis kode dan dengan demikian mengimpor secara dinamis
pasti terdengar seperti sesuatu yang tidak mungkin dilakukan di Angular.

Apakah Anda punya waktu mencoba fork repo dan hanya menghapus akses ke
window ? Sepertinya itu hanya digunakan di beberapa tempat yang bisa dengan mudah
dihindari.

Pada 27 Desember 2017 18:06, "cmddavid" [email protected] menulis:

Saya mencoba memperbaikinya menggunakan pendekatan berikut:

http://ideasintosoftware.com/typescript-conditional-imports/

Tapi saya tidak beruntung, karena kompiler AOT akan mulai mengeluhkan directive can
tidak lagi ditemukan.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/SebastianM/angular-google-maps/issues/1241#issuecomment-354144018 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AHTnkXZ85QbMrFT7timh9MPWDeL5piYiks5tEnkmgaJpZM4QmwTi
.

Belum, mungkin saya akan mencobanya akhir minggu ini. Saya bukan penggemar mengubah repo sumber, meskipun tidak dipertahankan saat ini, mungkin nanti. Tapi kurasa kita tidak punya pilihan lain. Saya suka saran untuk sepenuhnya menghapus referensi jendela, jika itu mungkin, itu akan bagus.

Yah, sudah dua tahun sejak pembaruan terakhir jadi itu sebabnya saya pikir
forking dalam contoh khusus ini, setidaknya sebagai solusi sementara,
tidak akan terlalu buruk.

Pada Kamis, 28 Desember 2017 pukul 01:04, cmddavid [email protected] menulis:

Belum, mungkin saya akan mencobanya akhir minggu ini. Saya bukan penggemar mengubah
sumber repo, meskipun tidak dipertahankan saat ini,
mungkin nanti. Tapi kurasa kita tidak punya pilihan lain. saya suka
saran untuk sepenuhnya menghapus referensi jendela, jika itu
mungkin itu bagus.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/SebastianM/angular-google-maps/issues/1241#issuecomment-354198599 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AHTnkfZdUcmrInBzlNL41wJ6znRzWVCoks5tEtsHgaJpZM4QmwTi
.

Saya memotong proyek js-marker-clusterer dan melakukan perbaikan. Ini mencegah inisialisasi MarkerClusterer ketika jendela tidak ditentukan (pada rendering sisi server). Jadi penanda clusterer berfungsi dengan benar dalam kedua kasus sekarang.

Ini diterbitkan di npm. https://www.npmjs.com/package/js-marker-clusterer-universal

Ketergantungan js-marker-clusterer harus diganti dengan js-marker-clusterer-universal agar berlaku.

@mbrezovsky kerja bagus, ini bekerja dengan baik untuk saya. Saya memang mendapatkan satu kesalahan terkait @agm/js-marker-clusterer menggunakan impor, sesuatu yang belum diizinkan di sisi Node.js/Firebase, jadi saya harus mengonversi kode ke ES2015 menggunakan Anthony Nahas solusinya diusulkan di sini: https: //github.com/SebastianM/angular-google-maps/issues/1052#issuecomment -331150772

Adakah pembaruan tentang masalah ini?

@AoschkA Saya masih menggunakan solusi seperti yang disebutkan dalam komentar saya sebelumnya. Anda dapat menemukan contoh saya di sini: https://github.com/cmddavid/js-marker-clusterer.git

@cmddavid Readme Anda baru saja menjelaskan cara menginstal agm/js-marker-clusterer. Bagaimana seseorang mengintegrasikan ini ke dalam proyek kita sendiri?

@AoschkA , repo hanyalah output yang dikompilasi, saya tidak memberikan instruksi apa pun, Anda dapat menambahkannya ke package.json Anda seperti ini:

"@agm/js-marker-clusterer": "git+https://github.com/cmddavid/js-marker-clusterer.git"

Saat Anda menginstalnya, Anda akan memiliki js-marker-clusterer tanpa jendela adalah kesalahan yang tidak ditentukan, dan dikompilasi ke ES2015 sehingga kompatibel dengan layanan seperti Firebase.

Thx itu berhasil. Alangkah baiknya jika ini bisa diterapkan di RUPS sekalipun. Tapi saya menghargai solusinya @cmddavid !

@cmddavid saya buat seperti yang Anda katakan, tetapi ada kesalahan ERROR di ./node_modules/@agm/js-marker-clusterer/services/managers/cluster-manager.js
Modul tidak ditemukan: Kesalahan: Tidak dapat menyelesaikan 'js-marker-clusterer-universal' di '.\node_modules\@agmjs-marker-clusterer\services\managers'

@maksimbykov dapatkah Anda mengonfirmasi js-marker-clusterer-universal ada di folder node_modules Anda? mungkin tidak sepenuhnya terinstal, kalau-kalau Anda bisa menjalankan npm i --save js-marker-clusterer-universal . Juga sesuatu yang aneh tampaknya terjadi dengan jalur file di sana. Yang pertama memiliki garis miring ganda // dan yang kedua melewatkan garis miring terbalik \ antara node_modules dan @agm .

Juga layak disebutkan saya tidak memeriksa apakah paket tersebut masih berfungsi dengan sudut 6.

@cmddavid terima kasih banyak! mungkin kemarin aku lelah dan lalai

Masalah ini secara otomatis ditandai sebagai basi karena tidak ada aktivitas terbaru. Ini akan ditutup jika tidak ada aktivitas lebih lanjut yang terjadi. Terima kasih atas kontribusi Anda.

"@agm/js-marker-clusterer": "git+ https://github.com/cmddavid/js-marker-clusterer.git " maaf tapi tidak berhasil (jangan instal apa pun)

Saya memotong proyek js-marker-clusterer dan melakukan perbaikan. Ini mencegah inisialisasi MarkerClusterer ketika jendela tidak ditentukan (pada rendering sisi server). Jadi penanda clusterer berfungsi dengan benar dalam kedua kasus sekarang.

Ini diterbitkan di npm. https://www.npmjs.com/package/js-marker-clusterer-universal

Ketergantungan js-marker-clusterer harus diganti dengan js-marker-clusterer-universal agar berlaku.

Terima kasih banyak, Anda baru saja menyelamatkan saya ... pujian :)

saya masih memiliki masalah ini, mengapa ditandai sebagai ditutup??

Anda benar-benar menurunkan penjelasan tentang mengapa itu ditutup. Anda telah melihat mengapa itu ditutup.

Anda benar-benar menurunkan penjelasan tentang mengapa itu ditutup. Anda telah melihat mengapa itu ditutup.

jadi sekarang kita bisa membukanya kembali :dancer:

lagi pula tidak lebih mudah untuk mengimpor js-marker-clusterer di dalam perpustakaan dan membuat modul yang dapat diekspor?

saya melakukan ini pada milik saya:

https://github.com/alexnoise79/js-marker-clusterer (lihat src/markerclusterer.js)

dan kemudian pada:
node_modules/@agm/js-marker-clusterer/fesm2015/agm-js-marker-clusterer.js

saya mengganti deklarasi Markerclusterer dengan:

impor * sebagai MarkerClusterer dari 'js-marker-clusterer';

ini berfungsi dan kompilasi ssr 100%

Solusi saya berdasarkan komentar @mbrezovsky di atas - jadi

"install:clusterer-universal": "npm i js-marker-clusterer-universal && rm -rf node_modules/js-marker-clusterer && mv node_modules/js-marker-clusterer-universal node_modules/js-marker-clusterer",
"postbuild": "npm run install:clusterer-universal"

dan itu akan dipasang setelah semua dan diganti.
Dan SSR bekerja! :)

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

dineshkumar20 picture dineshkumar20  ·  3Komentar

Subhojit1992 picture Subhojit1992  ·  3Komentar

n1t3w0lf picture n1t3w0lf  ·  3Komentar

shedar picture shedar  ·  4Komentar

Halynsky picture Halynsky  ·  3Komentar