Angular: NgModule pada Proyek Besar

Dibuat pada 7 Agu 2016  ·  144Komentar  ·  Sumber: angular/angular

Saya mengirimkan ... (centang satu dengan "x")

[X] feature request / proposal

Saya telah membaca tentang NgModule dan saya ingin memaparkan beberapa kasus penggunaan yang saya tidak sepenuhnya yakin dengan proposal saat ini (https://docs.google.com/document/d/1isijHlib4fnukj-UxX5X1eWdUar6UkiGKPDFlOuNy1U/pub) mempertimbangkan .

Konteks

Saya adalah bagian dari tim yang membangun Kerangka Kerja Perusahaan (berdasarkan Angular 2). Kerangka kerja ini kemudian akan menjadi dasar untuk aplikasi lain dalam ekosistem yang sama.

Kami telah membagi kerangka kerja menjadi proyek/modul yang lebih kecil (anggap mereka sebagai paket npm yang terpisah). Modul ini adalah kumpulan kontrol (yang kemudian digunakan kembali di seluruh modul lain) atau halaman yang menggunakan kontrol tersebut.

Contoh

Contoh cepat dapat berupa:

Modul Kontrol

import {Component} from "@angular/core";

@Component({
   selector: "my-combobox",
   ...
})
export class MyComboBox{

}

Modul Daftar Periksa
// Modul daftar periksa tergantung pada modul Kontrol. Kontrol diperlakukan sebagai modul pihak ke-3.

import {Component} from "@angular/core";
import {MyComboBox} from "controlsmodule/components/mycombobox";
// Please note that we are only loading a specific component within the module, not all components inside that module.

@Component({
     selector: "my-checklist-page",
     directives: [MyComboBox, ...],
     ...
})
export class ChecklistPage{

}

Bootstrap tidak mengetahui modul Kontrol dan Daftar Periksa. Mereka malas dimuat tergantung interaksi pengguna. Dalam hal ini, jika pengguna menavigasi ke Checklist, komponen ChecklistPage akan dimuat dan kemudian MyComboBox juga akan mengikuti (karena _import_ dibuat oleh ChecklistPage)

Modul daftar periksa memiliki selusin komponen lainnya. Masing-masing tergantung pada selusin komponen lain dari beberapa modul.

Ini tidak praktis (untuk tidak mengatakan hampir tidak mungkin) untuk memiliki semua komponen yang diimpor ke dalam deklarasi NgModule. Kita berbicara tentang beberapa ratus komponen yang _mungkin_ digunakan selama waktu aplikasi dijalankan.

Selain itu, aplikasi harus bersifat modular dan lazy load jika memungkinkan. Interaksi yang berbeda dalam aplikasi akan menyebabkan modul yang sama sekali berbeda dimuat.

Perilaku yang diharapkan/diinginkan

Solusi saat ini, dengan arahan cakupan komponen, berfungsi seperti pesona untuk kasus penggunaan ini. Tidak yakin bagaimana ini akan dimainkan dengan NgModule.

Lebih dari itu, saat ini kita bisa melihat dengan jelas dependensi yang dibutuhkan oleh masing-masing komponen (dalam hal ini ChecklistPage). Membuat perawatan yang jauh lebih mudah.

Mengimpor semua komponen yang diperlukan ke dalam NgModule, dan kemudian menggunakannya secara tidak jelas pada beberapa komponen tampaknya merupakan solusi yang fantastis untuk aplikasi kecil. Saya merasa bahwa dalam pengembangan jangka panjang, dengan beberapa iterasi selama beberapa tahun, dengan rotasi tim, ... memiliki setiap komponen secara eksplisit menyatakan pada apa itu tergantung tanpa melihat ke dalam template (dan memiliki kesalahan kompilasi ketika ada sesuatu yang hilang) adalah bagus keuntungan.

Kesimpulan

Tolong beri tahu saya jika saya jelas dalam penjelasan saya. Tujuan dari masalah ini adalah untuk meningkatkan kesadaran tentang situasi ini dan mendapatkan umpan balik dari Anda tentang cara untuk melanjutkan.

Kami siap menunjukkan kepada Anda pekerjaan kami saat ini, kami memiliki beberapa ratus komponen Angular 2 di 8 proyek yang dikembangkan pada tahun lalu (sejak alpha 27).

Komentar yang paling membantu

Terima kasih atas umpan balik semuanya, maaf butuh waktu lama untuk mendapatkan balasan - kami sangat sibuk selama seminggu terakhir (memigrasikan aplikasi Google internal ke NgModules, jadi kami juga merasakan kesulitan refactoring)

Biarkan saya melihat apakah saya dapat menjernihkan beberapa pertanyaan dan kesalahpahaman di sini.

Hal pertama yang harus dipahami tentang @NgModule() (dan @Component dan dekorator Angukar lainnya) adalah bahwa mereka murni mengkompilasi konstruksi waktu - mereka ada untuk memungkinkan kompiler sudut menemukan grafik ketergantungan dalam aplikasi.

Versi (yang disederhanakan) dari penampilan dekorator kami:

//simplified Component decorator
export function Component(componentConfig){
  return function(componentClass){
    Reflect.defineMetadata('annotations', componentConfig, componentClass);
  }
}

Mereka tidak mengubah atau memodifikasi perilaku kelas yang didekorasi dengan cara apa pun - mereka hanya melampirkan beberapa metadata. Angular menggunakan metadata itu untuk membangun aplikasi Anda dan mengkompilasi template.

Dalam mode JiT, ini terjadi "Just in Time" - di antara Anda memanggil bootstrapModule dan rendering komponen pertama Anda, kompiler Angular mengambil metadata yang dilampirkan ke kelas menggunakan Reflect API:

let metadata = Reflect.getOwnMetadata('annotations', componentClass);

Namun, dalam mode AoT, ini bekerja sedikit berbeda - pada waktu pembuatan, kami _statis_ (yaitu, tanpa mengeksekusi kode Anda) mengekstrak metadata yang sama dari kode sumber dengan memindai dekorator.

Ini berfungsi dengan baik ketika Anda mem-bootstrap satu komponen, tetapi kami telah mendengar banyak umpan balik dari pengembang yang melakukan hal-hal yang lebih kompleks - mem-bootstrap beberapa komponen root, atau mem-bootstrap komponen yang berbeda berdasarkan status autentikasi, dll.

Jadi sementara dekorator @Component memberi kami kemampuan untuk menganalisis Komponen secara statis, kami tidak memiliki kemampuan untuk menganalisis _Application_ secara statis dan andal

Hal-hal yang berada di bawah payung "aplikasi"

  • PLATFORM_DIRECTIVES/PIPE/PROVIDERS
  • hal-hal yang sebelumnya Anda tambahkan ke bootstrap()
  • pengaturan tingkat kompiler
  • beberapa komponen root
  • penggunaan sisi server.

NgModules memperkenalkan gagasan tentang serangkaian fitur yang dapat dianalisis secara statis. Yang menarik adalah bahwa dalam mode kompilasi AoT, kami menganalisis modul root Anda, dan _menghasilkan_ ModuleFactory untuk setiap Modul dalam aplikasi - ini adalah versi modul yang telah dikompilasi sebelumnya, yang berisi _hanya_ pabrik yang Anda rujuk secara statis dalam template dan yang Anda tandai sebagai "entryComponents"

Karena kami telah mengekstrak informasi yang diperlukan untuk kompilasi Ahead-of-Time, kami sebenarnya dapat menggoyang dekorator (ngc akan menangani ini secara otomatis untuk final) - dan daripada menggabungkan aplikasi Anda mulai dari Modul root Anda, Anda mulai di root Module_Factory_ yang Anda buat, yang hanya berisi kode yang benar-benar digunakan dalam aplikasi Anda, jadi Anda tidak membayar penalti untuk modularitas, dan alat seperti rollup dan webpack2 dapat bekerja _lebih_ efisien

lebih banyak untuk mengikuti di balasan berikutnya ...

Semua 144 komentar

Tampaknya bagi saya ngModules tidak melarang pengaturan yang Anda tuju, apakah Anda sudah memainkannya? Anda dapat memiliki beberapa modul berbeda dan melakukan lazy loading, dll. http://plnkr.co/edit/NAtRQJBy50R19QAl90jg?p=info

Untuk sesuatu yang lebih mirip dengan apa yang tampaknya Anda coba lakukan, perhatikan transisi material2: https://github.com/angular/material2/pull/950/files

Hai @qdouble ,

Terima kasih atas balasan cepatnya.
Melihat https://github.com/jelbourn/material2/blob/ecbb4f42e0473899f6ad15d8e4ed8f262ded7a99/src/components/button-toggle/button-toggle.ts , apakah Anda mengatakan bahwa untuk mencapai fungsi yang sama yang kita miliki sekarang, kita perlu untuk mendeklarasikan NgModule pada setiap komponen? (itu yang ditambahkan di akhir file kan?)

Juga, itu tidak mencakup masalah pemeliharaan yang saya sebutkan di pernyataan awal saya. Memiliki dependensi setiap komponen/direktif yang dideklarasikan pada dekoratornya, bagi saya, merupakan keuntungan besar yang ingin saya pertahankan.

@jpsfs jika Anda ingin membuat ruang lingkup individual untuk setiap komponen, maka saya kira Anda harus membuat ngModules yang berbeda untuk masing-masing komponen. Meskipun ini dapat membuat lebih banyak kode dalam kasus Anda, saya kira itu akan membuat lebih sedikit kode untuk sebagian besar orang lain dengan melingkupi modul saya alih-alih per komponen.

Sejauh masalah kedua, Anda dapat mendeklarasikan ngModule dan komponen tepat di sebelah satu sama lain, jadi sementara itu akan menambahkan 3 atau 4 baris kode tambahan ke file Anda, saya tidak berpikir itu menciptakan masalah besar.

Saya akan mengatakan sebagian besar kasus penggunaan tidak memerlukan arahan cakupan per komponen, tetapi dalam kasus itu, ngModules masih mendukungnya untuk beberapa baris kode lagi.

@qdouble Terima kasih.

Saya tidak yakin ini adalah situasi atau/atau, saya dapat melihat kedua skenario bekerja bersama, tidak perlu menghapus fungsi yang sudah kita miliki. Jika seseorang ingin menggunakan modul, saya dapat melihatnya sebagai tambahan yang bagus. Sementara itu, kerangka kerja dapat bekerja tanpa modul (seperti yang berfungsi saat ini). Saya percaya bahwa bahkan masalah kompilasi offline dapat diselesaikan dengan hal-hal seperti saat ini.

Saya membiarkan ini terbuka untuk melihat apakah seseorang memiliki sesuatu untuk ditambahkan ke masalah ini.

@jpsfs mengerti, jika saya berada dalam situasi Anda, saya pasti lebih suka mereka membiarkan kedua opsi terbuka :)

Mereka memang menulis alasan untuk menghentikan arahan komponen dalam dokumen yang Anda posting, sejauh itu membuat dua cakupan, mereka berpikir lingkup ngModule cukup kecil dan lebih sesuai dengan model ES6.

Seorang anggota tim juga menyebutkan sebelumnya bahwa umumnya bermasalah untuk memiliki dua cara berbeda untuk melakukan sesuatu ... dan dalam jangka panjang, saya dapat melihat masalahnya di sini .... jika Anda memiliki beberapa proyek di mana orang menggunakan ngModules dan proyek lainnya jika tidak ada, itu menciptakan lebih banyak masalah pemeliharaan, pelatihan, dan kompatibilitas.

Tidak pernah tahu ke mana arah proyek ini sampai final, jadi kita akan lihat apakah mereka mempertimbangkan apa yang Anda katakan.

Bahkan saat ini saya sedang merancang Arsitektur untuk Aplikasi Perusahaan yang besar.
Tidak seperti situasi Anda @jpsfs , saya senang dengan NgModules dan cukup banyak mendasarkan arsitektur aplikasi saya di sekitar NgModule.

Setiap Modul akan memiliki kumpulan rute dan dependensi komponennya sendiri. Kita tidak akan pernah bisa membuat fungsionalitas hanya dengan satu komponen, itu membutuhkan Routes, setidaknya satu Smart Component dan beberapa Dumb Components and Services untuk menyertainya. Colokkan ini semua ke dalam Modul dan Anda siap melakukannya.

Datang ke pemuatan lambat, alih-alih memuat kode untuk setiap komponen, tampaknya bagus bahwa setiap kode NgModule akan dimuat sekaligus, sehingga fungsionalitas Anda dapat digunakan sepenuhnya setelah diunduh.

Membuat hierarki Modul juga jauh lebih sederhana, dan menyediakan fitur Plug and Play yang hebat secara gratis.

Kami juga sedang mengerjakan aplikasi dengan komponen yang cukup banyak (Bukan ratusan tapi puluhan). Tidak ada kebutuhan arsitektur bagi kita untuk membagi aplikasi ini menjadi beberapa modul (lazy-loaded), tetapi sekarang mengimpor semua komponen tersebut ke dalam file bootstrap dan meneruskannya ke declarations entah bagaimana terasa salah dan merusak enkapsulasi komponen . Seperti yang dikatakan @jpsfs , sebelumnya sangat jelas komponen dan arahan mana yang digunakan oleh komponen lain. Jadi saya juga akan menghargai untuk memiliki pilihan:

  • Jika itu adalah arahan yang cukup umum digunakan, nyatakan di modul
  • Jika itu seperti TaskListItem impor saja di TaskList .

Mungkin beberapa anggota inti dapat memberi tahu lebih banyak tentang keputusan untuk menghentikan pendekatan kedua. Setelah bekerja dengannya selama beberapa bulan sekarang, rasanya cukup bagus;)

Untuk menggemakan poin @choeller , rasanya aneh menjauh dari kemampuan untuk menyediakan enkapsulasi komponen.

Kekhawatiran khusus saya adalah bahwa sekarang nama komponen/pemilih bocor di seluruh aplikasi, sedangkan sebelumnya Anda dapat menggunakan kembali pemilih untuk komponen yang berbeda dengan memasukkan arahan khusus yang sesuai.

Sekarang semua penyeleksi harus unik per komponen, bukan? Atau apakah saya salah paham bagaimana ini bekerja?

Saya merasa bahwa fungsi aslinya cocok dengan manfaat serupa yang diberikan oleh emulasi bayangan-DOM CSS, karena kita tidak perlu terlalu khawatir tentang tabrakan pemilih, dll. di seluruh aplikasi besar. Itu adalah keuntungan besar IMO.

Pikiran pertama saya tentang ngModule adalah "Oh, itu seperti di sudut 1". Sebesar sudut 1 sudah, sudut 2 jauh lebih baik dalam banyak hal. Poin terbaik bagi saya adalah, Komponen membuat semacam pohon ketergantungan. Saya memiliki komponen utama dengan router yang mendefinisikan beberapa titik masuk dengan komponennya sendiri. Dan setiap komponen tahu apa yang dibutuhkannya, tidak ada alasan bagi komponen utama untuk mengetahui apa yang dibutuhkan oleh komponen di ujung pohon.
Sekarang kita kembali ke masa lalu yang indah dari sudut 1, di mana kita memiliki definisi modul raksasa.
Ingat saat titik masuk aplikasi Anda terlihat seperti ini?

angular.module("myApp")
.controller("…")
.controller("…")
.controller("…")
.controller("…")
.controller("…")
.controller("…")
.component("…")
.component("…")
.component("…")
.component("…")
.component("…")
.component("…")
.directive("…")
.directive("…")
.directive("…")
.directive("…")
.directive("…")
.directive("…")
.directive("…")
.service("…")
.service("…")
.service("…")
.service("…")
.service("…")
.service("…")

Saya pikir ini milik masa lalu. Saya mulai bekerja dengan ng-metadata untuk meningkatkan proyek sudut 1 lama dan bersiap untuk migrasi. Saya sangat menyukai fakta, bahwa ia memiliki pohon ketergantungan dan bukan daftar "apa yang mungkin muncul di aplikasi ini" global.

Hal ini membuat komponen yang dapat digunakan kembali menjadi lebih sulit. Saya tidak mengerti bagaimana ini membuat segalanya lebih baik memiliki segalanya dalam lingkup global/modul, saya pikir tim ng2 telah menyerah pada pengguna ng1 yang tidak menginginkan perubahan.

@DaSchTour @damiandennis Saya memahami kritik terhadap arsitektur ini, namun, menyebutnya sebagai semacam cakupan global tidak akurat, metodologi yang mereka sarankan Anda ambil adalah memiliki modul fitur: https://angular.io/docs/ts /latest/guide/ngmodule.html#! #fitur-modul

@qdouble Nah, jadi pada akhirnya itu hanya mengubah semua Komponen menjadi Modul. Meskipun ini diumumkan sebagai perubahan untuk mengurangi kode boilerplate, ini memperkenalkan banyak kebutuhan boilerplating.

Sementara sampai RC4 komponen untuk setiap "halaman"/tampilan aplikasi sudah cukup, tahu saya harus membuat modul, komponen, dan perutean untuk setiap tampilan. Saya mendapatkan niat. Tapi entah bagaimana saya mendapat kesan, bahwa itu dirancang untuk membuat beberapa hal lebih mudah sementara tidak menyangkut banyak hal lainnya. Dan bahkan dengan pola modul fitur saya harus memotongnya sangat kecil untuk menghindari ketergantungan, dengan menambahkan semua yang mungkin diperlukan karena saya tidak dapat melihat bagian mana dari aplikasi saya yang membutuhkan komponen mana.

Pada akhirnya modulnya sekecil itu, sehingga mereka memiliki daftar ketergantungan berulang yang serupa seperti komponen saat ini.

Pada akhirnya, itu tidak menyelesaikan apa yang dirancang dan hanya menambah banyak pekerjaan. Saya merasa ada ketidaksesuaian antara desain dan kenyataan di sini.

pengembang malas/kekurangan waktu dan mengambil jalan pintas. Ini mendorong pengembang untuk mengambil rute cepat dengan memasukkan semua yang ada di bootstrap. Setidaknya dengan komponen ada beberapa persyaratan untuk memasukkan dependensi Anda. Ya, mereka mungkin juga malas dan membuat satu komponen untuk seluruh aplikasi tetapi itu akan lebih mudah untuk diperbaiki karena semua dependensi ada dalam komponen tersebut yang tidak tercampur antara file bootstrap dan setiap file komponen dalam aplikasi.

@DaSchTour jika masing-masing dan setiap komponen membutuhkan ruang lingkupnya sendiri, maka ya itu akan membuat lebih banyak boilerplate ... tapi saya menganggap bahwa tim ng berpendapat bahwa bagi kebanyakan orang, membuat modul baru untuk setiap bagian fitur sudah cukup dan beberapa komponen akan dapat hidup di setiap ruang fitur.

Sekarang jelas, tidak ada solusi yang cocok untuk semua dan memiliki arahan level komponen mungkin lebih sederhana bagi sebagian orang. Namun, tampaknya banyak komentar di sini menyiratkan bahwa mereka ingin Anda membuat aplikasi dengan satu pohon ngModule besar...

Saya pikir itu lebih produktif jika kritik didasarkan pada saran desain aktual mereka daripada pola desain manusia jerami yang tidak mereka sarankan (yaitu membuat aplikasi perusahaan yang hanya satu ngModule besar)

@qdouble pola desainnya sederhana. Ini menggunakan pohon dependensi alih-alih memindahkan dependensi ke lingkup modul global. Saya kira poin utamanya adalah, komponen yang dapat digunakan kembali sekarang harus berupa modul, bahkan jika mereka sangat kecil dan hanya memiliki fungsionalitas yang sangat sedikit. Material2 sudut adalah contoh yang sangat bagus. Tombol adalah modul, termasuk satu komponen. Mungkin itu kesalahpahaman umum dari banyak pengembang, bahwa modul adalah sesuatu yang berisi lebih dari sekadar tombol. Dan sekarang mari kita berpikir selangkah lebih maju. Hanya mengikuti ide dari artikel ini https://angularjs.blogspot.com/2016/08/angular-2-rc5-ngmodules-lazy-loading.html Saya menemukan diri saya pada intinya, bahwa saya memiliki banyak modul yang impor daftar modul material2 sudut dan masing-masing modul ini terdiri dari satu komponen.
Sebenarnya inilah yang dilakukan angular material2.

Tidak ada yang benar-benar mengerti maksudnya, mengapa kita sekarang harus membungkus "semua" komponen kita ke dalam modul. Atau mungkin kita harus melihat ini sebagai bagian dari deklarasi. Dependensi komponen sekarang menjadi modul dan definisi komponen seperti semula.

Saya kira intinya adalah, ngModules bukan hanya tambahan yang bagus untuk membuat segalanya lebih mudah tetapi kita dipaksa untuk mengubah segalanya. Mungkin seseorang harus membuat penjelasan yang jelas mengapa keduanya tidak bisa hidup berdampingan.

@DaSchTour ya, saya setuju bahwa jika setiap komponen yang Anda buat membutuhkan modulnya sendiri, maka menggunakan ngModules membuat lebih banyak boilerplate ... Saya hanya menganggap bahwa tim tidak berpikir bahwa kebanyakan orang akan membutuhkan tingkat pemisahan itu untuk setiap komponen.

Saya menemukan diri saya pada titik, bahwa saya memiliki banyak modul yang mengimpor daftar modul material2 sudut dan masing-masing modul ini terdiri dari satu komponen.

Anda akan menggunakan modul bersama untuk ini: https://angular.io/docs/ts/latest/guide/ngmodule.html#! #shared-modul

Sekarang, saya tidak begitu yakin mengapa mereka berpikir bahwa perlu untuk benar-benar menghapus kemampuan untuk memiliki cakupan komponen, tetapi bagi saya, beberapa kritik membuat penggunaan ngModules lebih sulit daripada yang sebenarnya atau membuat desain tampak lebih ceroboh dari yang sebenarnya.

Saya pikir kritik untuk menghapus arahan/pipa cakupan komponen benar-benar valid. Namun, saya rasa tidak perlu membuatnya tampak seperti tidak ada pola desain yang bagus untuk ngModules.

@qdouble Saya pikir tidak ada yang meragukan bahwa ada pola desain yang bagus untuk ngModules. Tapi dari apa yang saya pahami modul hanyalah pembungkus di sekitar sekumpulan komponen, arahan dan layanan untuk mengeksposnya adalah unit ke aplikasi. Itu valid dan ide bagus. Tetapi mengapa saya harus mendefinisikan dependensi (yang mungkin hanya ada di dalam modul) untuk modul dan bukan untuk komponen.

Mengambil contoh dari @choeller
Modul TaskDashboard memiliki hal-hal berikut:

  1. Komponen Daftar Tugas
  2. Komponen Tugas
  3. Komponen Filter Tugas
  4. Layanan Tugas

Komponen Taskitem hanya diperlukan di dalam Tasklist dan Tasklist bergantung pada Taskitem Component. Filter Tugas tidak memerlukan Komponen Item Tugas. Sekarang saya tidak memiliki Taskitem sebagai ketergantungan dalam Tasklist. Langkah selanjutnya adalah saya membuat modul TaskSearch. Saya menambahkan hal-hal berikut.

  1. Komponen Daftar Tugas
  2. Komponen pencarian tugas
  3. Layanan Tugas

Yah, saya melewatkan Komponen Taskitem dan rusak. Tasklist selalu bergantung pada Taskitem, tetapi ketergantungan ini disembunyikan di dalam modul. Menggunakan kembali komponen menjadi lebih sulit dan menciptakan sumber kesalahan tambahan.

Oke, saat membaca lebih lanjut melalui panduan modul, saya menemukan baris ini

Komponen, arahan, dan pipa harus milik tepat satu modul.

Jadi contoh persisnya menunjukkan keprihatinan yang diangkat di sini. Tidak boleh ada komponen yang dibagikan. Jadi dari contoh saya, saya harus membagi semuanya menjadi modul.

Saat mengerjakan kesalahan aneh dan tidak sulit dipahami yang muncul saat menggunakan ngModule, saya juga menemukan, bahwa memperluas komponen sekarang tidak berfungsi sebaik sebelumnya. Saya memiliki satu set komponen dengan dependensi yang diperlukan yang bisa saya perpanjang. Sekarang saya harus berhati-hati mengimpor dependensi dalam modul yang saya sertakan komponen tambahan saya.

@DaSchTour dalam contoh Anda, Taskitem harus menjadi bagian dari Modul Daftar Tugas ... sehingga akan menjadi dua komponen dalam satu modul secara logis, bukan satu untuk masing-masing.

Seperti yang ditunjukkan @sirajc , pola desain tipikal adalah memiliki satu komponen pintar teratas, diikuti oleh komponen bodoh tambahan... pola komponen atau dengan pola fitur terkait), bukan hanya satu komponen per modul kecuali Anda hanya membuat komponen pihak ke-3 atau semacamnya.

@qdouble @DaSchTour Memang benar bahwa arsitektur baru tidak selalu berarti bahwa Anda mencantumkan semua komponen Anda dalam satu file, tetapi melihat aplikasi yang sedang kami bangun, saat ini saya akan setuju dengan pernyataan @DaSchTour ini

Saya merasa ada ketidaksesuaian antara desain dan kenyataan di sini.

Jadi kami memiliki cukup banyak komponen yang mewakili unit kecil pada halaman seperti TaskListItem yang 100% terikat pada tampilan khusus. Membuat Modul untuk masing-masing halaman itu akan menjadi pekerjaan yang berlebihan. Dalam kasus kami, ada sangat sedikit alasan untuk membagi menjadi beberapa modul tetapi lebih banyak alasan untuk mengenkapsulasi komponen.

tl; dr
Sangat keren untuk dapat mendefinisikan beberapa dependensi pada level modul, tetapi sangat menyedihkan, bahwa kami tidak dapat lagi mendefinisikan dependensi pada level komponen

@DaSchTour , Dalam komponen tombol material2 diikat ke modul untuk membuatnya mandiri. Mereka yang perlu menggunakan tombol dapat mengimpor ButtonsModule . Juga jika Anda melihat kode Modul, itu berisi dua komponen MdButton dan MdAnchor , membungkus kemudian dalam ButtonsModule membuat segalanya lebih mudah digunakan

Saya bertanya-tanya apakah mungkin untuk membuat beberapa objek komponen/modul hibrida yang menggabungkan dua konsep menjadi satu untuk mencegah duplikasi file. Pada dasarnya dapat mendeklarasikan komponen sebagai modul sekali, dan kemudian mengimpornya sebagai modul, sesuai kebutuhan. Itu akan menghormati pendekatan saat ini, tetapi meminimalkan boilerplate.

@choeller Saya setuju bahwa memiliki modul adalah tambahan yang bagus, menghapus dependensi pada tingkat komponen namun sepertinya salah.

Menumpuk apa yang ditulis orang lain di atas, saya pikir ide inti di sini bukanlah untuk mengalami kesengsaraan proyek besar dengan modul besar dengan ratusan komponen di dalamnya. Sebaliknya, ini adalah untuk membangun aplikasi dari NgModules berukuran sedang dalam jumlah yang wajar. Cukup besar sehingga tidak sepele, cukup kecil sehingga Anda tidak memiliki banyak; dibagi sepanjang garis patahan yang cenderung memfasilitasi penggunaan kembali dan modularitas dalam pengertian ilmu komputer kuno tentang kohesi tinggi dan kopling rendah.

Dengan demikian, modul harus menjadi konsep yang cukup berguna untuk dimainkan di proyek besar.

Itu diringkas dengan sangat baik @kylecordes. NgModules membantu dalam komposisi Aplikasi yang bagus. Modul kecil yang dapat digunakan kembali membentuk seluruh aplikasi.
Manfaat lainnya termasuk ketersediaan arahan di sekitar. Sebelumnya kami biasa menambahkan ROUTER_DIRECTIVES di seluruh aplikasi. Sekarang RouterModule.forRoot() melakukannya untuk kita.
BrowserModule, CommonModule, FormsModule lebih masuk akal daripada memasukkan arahan melalui setiap komponen.

MaterialModule di sisi lain menyediakan segalanya dan jika Anda membutuhkan kontrol yang lebih baik maka ButtonsModule dll akan membantu kami.
Itulah keindahan komposisi. Rangkullah dan ciptakan Symphony Anda

Di atas ini adalah LazyLoading. Jika bukan karena NgModules, bagaimana seseorang dapat menentukan jumlah komponen dan layanan yang perlu digabungkan untuk membuat satu unit Routable. Anda tidak dapat mengunduh file yang longgar karena ini akan menyebabkan tidak adanya permintaan jaringan yang besar. Jika tidak, Anda perlu membuat bundler tempat Anda mencantumkan semua file dependen untuk membuat satu bundel. NgModule melakukan ini dengan sintaks intuitif.

@kylecordes

Menumpuk apa yang ditulis orang lain di atas, saya pikir ide inti di sini bukanlah untuk mengalami kesengsaraan proyek besar dengan modul besar dengan ratusan komponen di dalamnya. Sebaliknya, ini adalah untuk membangun aplikasi dari NgModules berukuran sedang dalam jumlah yang wajar. Cukup besar sehingga tidak sepele, cukup kecil sehingga Anda tidak memiliki banyak; dibagi sepanjang garis patahan yang cenderung memfasilitasi penggunaan kembali dan modularitas dalam pengertian ilmu komputer kuno tentang kohesi tinggi dan kopling rendah.

Bukankah garis kesalahan itu akan sangat berbeda untuk pengembang aplikasi vs pengembang perpustakaan. Pengembang perpustakaan seharusnya menjadi minoritas, tetapi itu tampaknya menjadi keluhan utama. Saat membangun kerangka kerja yang dapat digunakan kembali, tujuan ingin meminimalkan ukuran modul menyebabkan banyak kebisingan tambahan.

@sirajc

Di atas ini adalah LazyLoading. Jika bukan karena NgModules, bagaimana seseorang dapat menentukan jumlah komponen dan layanan yang perlu digabungkan untuk membuat satu unit Routable. Anda tidak dapat mengunduh file yang longgar karena ini akan menyebabkan tidak adanya permintaan jaringan yang besar. Jika tidak, Anda perlu membuat bundler tempat Anda mencantumkan semua file dependen untuk membuat satu bundel. NgModule melakukan ini dengan sintaks intuitif.

Saya dapat dengan mudah melakukan ini dengan router lama hanya menggunakan komponen yang berfungsi sebagai wadah untuk bagian dari aplikasi saya. Modul ini hanya membawa komponen langsung yang dibutuhkannya, yang akan membawa dependensinya sendiri. Setiap pemuat modul yang layak akan dapat memuat rantai ketergantungan (melalui impor) komponen itu tanpa menyertakan setiap sub-ketergantungan di komponen tingkat atas. Hal yang sama berlaku untuk bundler yang harus menggunakan semacam logika resolusi modul. Singkatnya: tidak ada alasan, dari perspektif pemuatan lambat, mengapa pengembang perlu mendeklarasikan semua dependensi yang terkandung dalam komponen tingkat atas.

Benar-benar terasa seperti ngModule adalah solusi dalam mencari masalah ...

Ada sesuatu yang bisa dikatakan untuk dapat membuka komponen apa pun, melirik array arahannya, dan tahu persis komponen/arahan apa yang menjadi sandarannya. Apakah lebih bertele-tele karena harus mengimpor komponen tombol di seluruh banyak komponen yang menggunakannya? Ya, tapi saya lebih suka memiliki beberapa boilerplate tambahan dan memiliki hal-hal yang eksplisit dan segera dapat dipindai daripada mencari pohon komponen/modul untuk melihat bagaimana komponen Y menggunakan komponen X di templatnya tanpa pernah mengimpornya.

Argumen yang dibuat di atas adalah bahwa jika seseorang ingin memisahkan komponen satu sama lain, mereka bisa dibilang membuat modul untuk setiap komponen -- tetapi kemudian pada saat itu Anda menulis lebih banyak boilerplate daripada komponen asli yang pernah ada.

Jelas ada manfaat lain untuk ngModule yang belum saya bahas, dan sementara ada manfaat untuk dapat menggabungkan bagian-bagian dari aplikasi ke dalam modul fitur, rasanya seperti langkah mundur dalam hal kejelasan dan memiliki komponen yang dienkapsulasi menjadi potongan-potongan kode yang tidak bocor pelingkupan di semua tempat.

Bagian dari "penjualan keras" yang harus dilakukan tim ng2 kepada komunitas dari ng1 adalah "ya, Anda harus mengimpor dan mendeklarasikan arahan Anda untuk setiap komponen, tetapi percayalah kepada kami, Anda akan menghargai menjadi lebih eksplisit seiring bertambahnya aplikasi Anda". Saya sangat percaya pada penderitaan melalui sedikit pengulangan demi keterbacaan dan pemindaian dalam lingkungan tim skala besar di mana seorang anggota tim mungkin hanya mengerjakan subset komponen yang sangat kecil pada waktu tertentu.

Paling tidak, saya tidak melihat alasan mengapa ngModule dan properti directives/pipes tidak dapat hidup berdampingan. Alternatifnya adalah bahwa setiap komponen dalam setiap aplikasi yang ditulis untuk ng2, hingga RC5 sekarang menggunakan kode usang yang perlu direfactored secara non-sepele. Ini benar-benar bukan jenis perubahan yang saya harapkan selarut ini dalam pengembangan...jujur ​​ini cukup membingungkan.

ngModules pada dasarnya memerlukan penulisan ulang sebagian besar aplikasi jika ingin terstruktur dengan benar ... tetapi kesalahpahaman terbesar adalah bahwa mereka memaksa tingkat cakupan tertentu ketika kenyataannya modul Anda bisa sebesar atau sekecil yang Anda inginkan. menjadi.

Jika Anda benar-benar perlu membuat modul baru untuk setiap komponen, itu akan menghasilkan lebih banyak boilerplate = valid.

Sebagian besar aplikasi mengharuskan Anda membuat modul untuk setiap komponen = tidak valid (terutama jika Anda menggunakan pola komponen dan pola fitur yang cerdas/bodoh)

Untuk pertama kalinya hari ini, saya merasakan keletihan sisi klien/JavaScript yang telah disampaikan sejumlah rekan kepada saya. Saya telah kehilangan banyak waktu selama beberapa hari terakhir mencoba untuk refactor aplikasi RC4 kami untuk menggunakan modul RC5 baru.

Saya sangat setuju dengan sejumlah sentimen di utas ini, terutama tentang memberi pengembang pilihan dalam hal cara mereka ingin menyusun dependensi komponen mereka. Saya tidak suka ngModule yang lebih besar melemahkan grafik ketergantungan yang jelas antara komponen dan ngModules yang lebih kecil menambahkan kode boilerplate tambahan ke setiap komponen. Saat menganalisis sebuah modul, yang saya tahu adalah bahwa setidaknya satu dari komponen yang direferensikan membutuhkan barang dari impor modul atau deklarasi saudara. Jika saya memecah modul menjadi beberapa modul lain, pada dasarnya saya dibiarkan dengan coba-coba dalam menentukan dependensi mana yang dibutuhkan modul baru (pemeriksaan yang cermat terhadap templat komponen membantu).

Akhirnya, jika saya "lupa" untuk mengekspor komponen, komponen saya tidak dapat dirender, tidak ada kesalahan yang diberikan. Sangat mudah untuk menemukan jika Anda memiliki grafik modul yang sangat datar, hampir tidak mungkin ketika Anda memiliki sejumlah level!

Pada tahap ini saya sedih, kecewa dan berkecil hati. Saya telah mendapatkan tim pengembang dan pemangku kepentingan bisnis dengan teknologi yang sekarang saya tidak tahu apakah saya bisa maju. Saya sangat berharap keseimbangan yang lebih baik dapat ditemukan.

Pada tahap ini saya sedih, kecewa dan berkecil hati. Saya telah mendapatkan tim pengembang dan pemangku kepentingan bisnis dengan teknologi yang sekarang saya tidak tahu apakah saya bisa maju. Saya sangat berharap keseimbangan yang lebih baik dapat ditemukan.

Saya kira intinya di sini adalah, bahwa ada sejumlah besar pengembang yang menunggu teknologi ini siap untuk produksi dan meskipun disebut Kandidat Rilis, setiap kandidat baru membawa perubahan besar dan rasanya lebih seperti alfa.

Saya yakin banyak tim telah menghabiskan waktu berjam-jam untuk arsitektur aplikasi baru mereka dan sekarang semuanya gila.

Apa yang akan menjadi perubahan melanggar berikutnya? Saya bahkan tidak dapat membayangkannya, tetapi saya khawatir seseorang akan menemukan cara untuk memperkenalkan perubahan besar berikutnya.

Dari posting blog RC5:

Jika Anda telah menulis kode Angular 2 sama sekali, Anda mungkin bertanya pada diri sendiri "tetapi MENGAPA saya harus membuat daftar semua hal ini!?" - terutama jika Anda memperhatikan bahwa arahan dan pipa tertentu di Angular 2 adalah "khusus" - mereka tersedia untuk seluruh aplikasi Anda tanpa Anda melakukan apa pun ( *ngFor / *ngIf / *ngSwitch, misalnya).

Saya pribadi belum pernah melihat pertanyaan itu diajukan oleh siapa pun dalam beberapa waktu. Sampai RC5, tim Angular, sumber belajar online, buku, dll. semuanya telah menjelaskan mengapa deklarasi itu diperlukan -- dan sepertinya semua orang menerima (dan beberapa memeluk) fakta itu sejak lama.

Adapun pertanyaan tentang mengapa beberapa "istimewa" dan tidak perlu dideklarasikan, saya tidak berpikir siapa pun akan menentang adanya daftar arahan "tingkat rendah" yang kritis yang ada di mana-mana untuk menjamin "diberkati" sebagai tersedia secara global oleh pemegang platform (tim Angular).

Jika kode sudah ada untuk menangani pengangkatan arahan menjadi satu ngModule, dan kode itu berfungsi tidak terlihat oleh pengguna akhir, apa salahnya mengizinkan kedua pendekatan? Itu adalah pertanyaan asli, karena saya mungkin tidak menyadari beberapa seluk-beluk seputar apa yang mungkin terjadi jika pengembang mencampuradukkan pendekatan tersebut. Ada banyak "pilihan terpisah" lainnya di Angular 2 - model vs formulir yang digerakkan oleh templat, 3 pilihan bahasa yang berbeda, dekorator input/output/host vs pendekatan properti - apa salahnya pada yang lain pada saat ini?

Saya bisa melanjutkan, tetapi poin yang saya coba sampaikan adalah bahwa tim dan komunitas Angular telah menginvestasikan cukup banyak waktu untuk menyampaikan pesan bahwa menjadi lebih eksplisit adalah hal yang _baik_, hanya untuk masuk -- di _release kandidat 5_ sepanjang masa -- untuk memberi kami solusi yang tidak menjadi masalah selama beberapa waktu.

Adakah dari tim yang merasa ingin ikut campur? Saya tidak ingin ini menjadi ruang gema -- saya ingin mendengar sisi lain dari argumen tersebut. Sepertinya sesuatu yang begitu besar muncul tiba-tiba tanpa mempertimbangkan hal-hal seperti perkakas, pelatihan, atau seberapa dekat kita dengan rilis final.

Diskusi ini menimbulkan masalah yang sangat besar bagi banyak pengembang yang ingin mulai mengembangkan lebih awal dengan perubahan sudut 2: melanggar yang sangat diharapkan. Saya melakukan banyak bukti konsep berdasarkan sudut 2 sejak beta 17 dan membuat perusahaan dan organisasi penting mengadopsinya. Saya tidak menyesal tetapi saya juga tidak yakin saya melakukannya dengan baik. Beberapa proyek terbaru adalah POC dan pertempuran melawan Vue.js. Angular 2 jelas memenangkan pertarungan itu. Tapi hari ini, dengan semua penulisan ulang kode, perubahan yang melanggar, rilis yang tidak benar-benar RC, orang-orang mulai mengejar saya dan itu menjadi sangat serius. Itu tidak akan terjadi jika saya menawarkan pengembangan Vue atau React dan itu sangat membuat frustrasi karena Angular 2 dapat mendiskreditkan orang.

Sepertinya saya tidak memiliki definisi yang sama tentang Kandidat Rilis sebagai Tim Sudut.

Adapun topiknya, NgModule, saya benar-benar menandatangani bersama @jpsfs , jika Anda harus membuat daftar semua komponen dan komponen mikro Anda dalam deklarasi modul Anda, Anda sebaiknya memiliki fungsi prune di suatu tempat atau menjadi raja modelisasi karena sangat kuat, terlalu sensitif untuk proyek skala besar...

Saya pikir tingkat modularitas tambahan yang lebih tinggi ini hampir tak terelakkan; dan bahwa berbagai kerangka kerja yang bersaing pada akhirnya akan berakhir dengan sesuatu yang serupa.

Saya bertanya-tanya, apakah itu benar-benar perlu untuk membuat sistem modul berbutir kasar baru ini sepenuhnya ortogonal dengan sistem modul yang mendasarinya, atau apakah mungkin untuk membuat setiap direktori tingkat atas, dan semua modul Es6 yang terkandung di dalamnya, secara implisit terdiri dari NgModule berbutir kasar. Mungkin mekanisme yang digerakkan oleh konvensi seperti itu dapat ditambahkan di atas mekanisme saat ini, dan oleh karena itu hapus boilerplate NgModule untuk proyek yang bersedia mengikuti konvensi semacam itu.

(Tentu saja saya juga berbagi rasa frustrasi dengan orang lain di sini, dari perubahan signifikan di tahap "RC" ... Saya yakin tim inti, juga, jika mereka harus menyelesaikan semuanya, akan menyerang tingkat tinggi. modularitas, dan kekuatan yang mendorongnya (pemuatan malas, pra-kompilasi) lebih dekat ke awal proyek alih-alih pada tahap kandidat rilis. Begitulah kehidupan, selalu mudah untuk melihat ke belakang dan berpikir "baik jika kita telah mengetahui apa yang kita ketahui sekarang...")

Jika dukungan kompilasi adalah alasan utama di balik munculnya ngModule, itu pasti tidak boleh menggantikan lingkup berbasis komponen yang ada untuk arahan dan pipa.
Di sisi lain, berdasarkan konfigurasi rute dan dependensi, kompiler sudut secara teoritis dapat membagi sendiri kode aplikasi ke unit kompilasi (modul) yang sesuai.

Secara pribadi saya merasa perubahan ini membawa boilerplate rendah tanpa banyak keuntungan.

Saya dapat berargumen bahwa alih-alih menggunakan modul, kami dapat menggunakan komponen sebagai unit aplikasi. Ini mungkin yang dilakukan orang sebelum rc-5.

Jika modul diperlukan untuk keperluan internal kerangka kerja ini (seperti pemuatan lambat dan hal-hal terkait) maka modul tersebut harus disembunyikan dari pengembang entah bagaimana sehingga tidak mencemari kode dan membuat pengalaman pengkodean yang lebih buruk. Dan saya bahkan tidak berbicara tentang pemeliharaan...

Pertama kali saya melihat angular2 saya berpikir: 'Hei, mereka menuju ke arah yang benar dengan ini, sepertinya mereka belajar sesuatu dari angular 1'. Anda membuang modul internal dari sudut 1 dan sebagai gantinya menggunakan modul ES, perubahan lain juga disambut (komponen, TypeScript, dan sebagainya)

Tetapi semakin saya menunggu ini menjadi stabil, semakin membuat saya ngeri karena perubahan yang melanggar, kurangnya dokumentasi dan pesan kesalahan yang buruk. Sekarang Anda datang dengan NgModules ini dan pada dasarnya membatalkan setidaknya satu hal hebat yang Anda ubah sejak sudut 1.

Lebih buruk lagi, jika saya memiliki aplikasi yang dimulai dengan rc-2 atau 3 (yang secara teoritis hampir stabil), saya sekarang harus melakukan banyak pekerjaan untuk membuat aplikasi angular2 rc-5 yang bagus dan entah bagaimana harus menjelaskan pelanggan dan lainnya pengembang ini. Dan bahkan jika saya melakukannya, Tuhan tahu apa yang akan Anda ubah selanjutnya dan pekerjaan saya mungkin akan sia-sia.

Saya tahu angular 2 telah menjadi tahap awal untuk sementara waktu sekarang, tetapi kami adalah RC-5, orang-orang memiliki proyek yang cukup solid menggunakan Angular 2 sekarang dan Anda masih melakukan perubahan tidak hanya melanggar dari sudut pandang API tetapi juga melanggar sebagai cara berpikir dalam Angular.

Ini bukan ngFor yang baik dan beberapa impor berubah atau komponen injeksi berubah secara dinamis 3 kali dalam 5 rilis tetapi ini dapat saya terima dan pahami. Membawa perubahan yang tidak hanya merusak aplikasi tetapi cara berpikir pengembang dalam kerangka kerja ini sangat terlambat dalam siklus pengembangan yang sayangnya tidak dapat saya terima.

Bagaimanapun, seperti yang Anda lihat, banyak orang setuju dengan apa yang saya katakan dan beberapa bahkan lebih marah. Anda memiliki kerangka kerja besar yang dipercaya orang (karena sebagian besar Google) tetapi Anda tidak dapat mempertaruhkan segalanya atau Anda mungkin terkejut karena setiap orang memiliki pilihan (dan ketika berbicara tentang JS, ada BANYAK).

Jika Modul baru akan memiliki templat, itu bisa menjadi Komponen. Pikirkan tentang itu.

Langkah selanjutnya adalah memindahkan semua variabel dan fungsi dari Komponen ke dalam kelas Modul. Dengan serius. Kemudian kami memiliki perpustakaan pusat besar dari _semua tindakan yang mungkin_ dalam modul mengkilap kami. Ini akan luar biasa! Saya tidak tahu mengapa Anda berhenti di sentralisasi deklarasi dan dependensi. Ada banyak lagi baris kode terstruktur yang terdesentralisasi di sana!

Adakah yang bisa dari tim inti memiliki suara tentang semua ini? Dari catatan pertemuan mingguan terakhir, tim melanjutkan penghapusan API yang tidak digunakan lagi.

@mhevery

Seluruh pengangkatan ini merusak aplikasi saya dengan sangat halus ketika saya memutakhirkan hari ini.

  • Saya harus mengubah pemilih komponen dari kelas ke elemen, karena dalam komponen yang sama sekali tidak terkait, kelas itu digunakan untuk penataan dan tiba-tiba mulai membuat instance komponen.
  • Saya cukup yakin #10850 hanya ada, karena saya memiliki dua komponen yang disebut SpectrumComponent (satu halaman penuh untuk dinavigasi tanpa pemilih dan satu komponen "bersama" yang digunakan dalam beberapa komponen untuk visualisasi dengan pemilih). Mengangkat kemungkinan akan dibingungkan oleh itu - deklarasi directives: tidak.

Untuk komponen SVG saya, ini sekarang menjadi masalah yang lebih besar, karena saya tidak dapat menggunakan elemen khusus di sana. Saya belum tahu bagaimana cakupan ini untuk memastikan pemilih kelas mereka tidak memicu instantiasi komponen di mana pun (!) lain dalam aplikasi.

Tampaknya menjadi mode akhir-akhir ini untuk mengabaikan arti "Beta" dan "Kandidat Rilis" (ASP.NET Core menjadi contoh profil tinggi lainnya) dalam proyek-proyek besar. Tetapi dihadapkan dengan perubahan yang melanggar yang berpotensi merusak aplikasi secara diam-diam di mana saja lebih membuat frustrasi daripada yang seharusnya. Saya sangat berharap janji-janji yang datang dengan perubahan itu segera membuahkan hasil.

ngModules masuk akal. Menghapus kemampuan untuk mendeklarasikan/menyediakan di tingkat komponen tidak.

Contoh kecil

Saya memiliki aplikasi yang berisi sejumlah dialog yang berbeda (beberapa yang sederhana - sebut saja sederhana-1 dan sederhana-2, dan satu kompleks yang berisi komponen lain - sebut saja kompleks itu 3).

Saat ini saya memiliki struktur folder sederhana (jelas aplikasi ini tidak termasuk)

- dialogs
   - simple-1 (containing single component and template for simple-1 dialog)
   - simple-2 (containing single component and template for simple-2 dialog)
   - complex-3 (contains the main complex-3 component plus a number of other internal components)
      - internal-component-1
      - internal-component-2
      - internal-service-3

Bagi saya, ini adalah set fitur yang sempurna untuk dimasukkan ke dalam modul fitur yang terisolasi. Jadi saya menambahkan

   dialogs.module.ts
   - simple-1
   - simple-2
   - complex-3
      - internal-component-1
      - internal-component-2
      - internal-service-3

Dan saya menambahkan Simple1Component, Simple2Component dan Complex3Component sebagai deklarasi ke DialogsModule. Sempurna, bekerja dengan baik dan masuk akal.

Tetapi...

Bagaimana dengan semua komponen internal di kompleks-3. Saya sekarang memiliki dua pilihan

  • Tambahkan semua komponen dan layanan kompleks eksternal ke DialogsModule. Ini adalah keputusan yang buruk karena merusak enkapsulasi kompleks-3 karena sekarang semua yang ada di modul dialog tahu tentang internalnya (komponen-internal-1, komponen-internal-2, layanan-internal-3)
  • Jadikan complex-3 sebagai modul tersendiri. Ini memperbaiki masalah pelingkupan (dan saya yakin saya dapat mengekspor modul dari modul lain sehingga klien hanya perlu mengimpor modul pembungkus) tetapi sekarang meninggalkan saya dengan campuran komponen dan modul untuk grup serupa (dialog).

Tak satu pun dari ini benar-benar masuk akal, dan seiring skala aplikasi, konflik antara keduanya hanya akan meningkat.

Satu-satunya solusi yang masuk akal/jelas/dapat dipertahankan bagi saya adalah menggunakan modul untuk mengekspor komponen tingkat atas (simple-1, simple-2, complex-3) tetapi biarkan _component_ complex-3 mendefinisikan komponen internalnya sendiri.

/ cc: @robwormald

Saya telah memikirkan tentang apa yang @kylecordes katakan sebelumnya tentang menggunakan sistem modul TypeScript yang ada untuk mendefinisikan kumpulan kode courser grain, daripada menambahkan hal ngModules baru. Saya ingin mengirimkan contoh untuk dipertimbangkan, yang menggunakan modul TypeScript untuk mendefinisikan ngModules dengan cara 1-ke-1. Komentar dan pemikiran dipersilakan.

https://github.com/jbalbes/autoNgModule

10901

Saya mungkin melewatkan sesuatu, tetapi cara injeksi ketergantungan bekerja dengan modul yang tidak dimuat dengan malas mungkin menjadi masalah besar untuk "Proyek Besar" (milik saya tidak dan sudah menderita).

ini menarik. kami sudah memiliki aplikasi perusahaan di Angular1. dan kami menggunakan requirejs untuk mendefinisikan paket untuk berbagai modul (setiap modul berisi 10-20 arahan/layanan/filter). kami menggabungkan paket-paket ini ke dalam satu file untuk produksi (kecuali arahan utama). arahan malas dimuat ke dalam aplikasi saat digunakan (kami memiliki arahan inti yang malas memuat arahan yang diperlukan).

templat halaman perutean aplikasi kami ditempatkan di aplikasi cms, dan pengguna cms dapat menarik/melepas widget UI berbasis arahan utama di antara templat halaman yang berbeda (inilah sebabnya kami membutuhkan dukungan pemuatan lambat untuk arahan untuk mengurangi ukuran file skrip utama pada pemuatan browser sebagai sebagian besar aplikasi kami didasarkan pada widget berbasis direktif)

Angular1 memungkinkan untuk memuat arahan malas ke modul dengan mendapatkan referensi ke penyedia register.
apakah jenis komponen pemuatan malas ini ke modul dan mengompilasinya menjadi mungkin di Angular2?

Saya setuju dengan apa yang orang lain sarankan bahwa ngModules adalah solusi mencari masalah. Manfaat potensial dari LazyLoading dalam pikiran saya tidak membenarkan penghentian paksa arahan komponen/dependensi pipa. Mungkin saya salah di sini, tetapi saya merasa sebagian besar aplikasi tidak akan benar-benar melihat manfaat nyata dari Lazy Loading, yang bagi saya adalah satu-satunya manfaat sebenarnya yang disediakan oleh ngModules sama sekali.

Mungkin ngModules sedang mencoba (dan hei, mungkin itu akan berhasil) untuk membuat struktur/pola pengembangan lebih baik, tetapi berdasarkan sedikit yang saya lihat dan diskusikan tentang API sejauh ini, itu bergerak ke arah yang lebih rumit untuk ikuti dan pertahankan.

Juga, apakah kita benar-benar membutuhkan sistem modul lain?

Tidak ada yang bisa membantah bahwa NgModule menambahkan hal baru yang tidak harus kita tangani sebelumnya. Dan saya, seperti orang lain, sangat menghargai kesederhanaan pra-RC5, terutama dari program yang sangat kecil, yang telah hilang. Saya juga sangat rindu untuk dapat memberi tahu orang-orang bahwa Angular 1 memiliki sistem modulnya sendiri, tetapi dengan Angular 2 kami hanya menggunakan sistem modul dari bahasa yang mendasarinya. Ups.

Namun, sebenarnya ada cukup banyak orang, termasuk banyak pemimpin teknis dan pengambil keputusan lainnya di perusahaan besar yang mencoba membangun hal-hal besar, yang sangat tertarik pada pemuatan lambat dan pra-kompilasi template... Keduanya secara substansial diaktifkan oleh NgModul.

Namun satu hal lagi. Bagian yang paling saya sukai tentang modul Angular baru adalah namanya. Modul kata, itu sangat kelebihan beban. Saya membicarakan hal ini untuk beberapa pengembang lain di sini kemarin, dan kami lebih menyukai kata "paket", itu semacam menangkap ide yang sama dengan baik dan tidak memiliki banyak hal yang bersaing dengan nama yang sama, setidaknya tidak dalam ekosistem JavaScript.

@kylecordes masalah tentang nama https://github.com/angular/angular/issues/10087

Bukankah logika yang disajikan di sana juga mendiskualifikasi penggunaan kata 'modul', karena bertentangan dengan banyak, jika tidak lebih, konsep?

@Barryrowe sendiri tidak bisa mengatakannya dengan lebih baik - sepertinya sebagian besar aplikasi tidak akan mendapat manfaat dari ini - apakah itu hanya menambah kerumitan? Saya harap tidak.

Saya bertanya-tanya, apakah itu benar-benar perlu untuk membuat sistem modul berbutir kasar baru ini sepenuhnya ortogonal dengan sistem modul yang mendasarinya, atau apakah mungkin untuk membuat setiap direktori tingkat atas, dan semua modul Es6 yang terkandung di dalamnya, secara implisit terdiri dari NgModule berbutir kasar. Mungkin mekanisme yang digerakkan oleh konvensi seperti itu dapat ditambahkan di atas mekanisme saat ini, dan oleh karena itu hapus boilerplate NgModule untuk proyek yang bersedia mengikuti konvensi semacam itu.

Ini adalah poin kunci. ESModules bekerja sangat baik untuk menyusun aplikasi jika Anda menyusun aplikasi dengan benar. Misalnya, Anda dapat dengan mudah membuat ekspor yang sangat berlapis dengan mudah tersedia di tingkat teratas API Anda hanya dengan mengekspor ulang di tingkat yang lebih tinggi. Saya juga mendukung untuk menambahkan lebih banyak, opsional, konvensi ke kerangka kerja secara umum.

Pertama kali saya melihat angular2 saya berpikir: 'Hei, mereka menuju ke arah yang benar dengan ini, sepertinya mereka belajar sesuatu dari angular 1'. Anda membuang modul internal dari sudut 1 dan sebagai gantinya menggunakan modul ES, perubahan lain juga disambut (komponen, TypeScript, dan sebagainya)

Tetapi semakin saya menunggu ini menjadi stabil, semakin membuat saya ngeri karena perubahan yang melanggar, kurangnya dokumentasi dan pesan kesalahan yang buruk. Sekarang Anda datang dengan NgModules ini dan pada dasarnya membatalkan setidaknya satu hal hebat yang Anda ubah sejak sudut 1.

Memang, Angular 2 seharusnya memanfaatkan tumpukan teknologi web kaya yang muncul yang tidak tersedia saat AngularJS dikembangkan. Namun, sementara pembenaran untuk begitu banyak keputusan desain yang dibuat untuk Angular 2 adalah "Komponen Web harus didukung" ironisnya kerangka tersebut menyimpang dari standar dengan cara yang semakin meningkat. Sekarang ada alasan bagus untuk menyimpang dari standar, ketika standarnya buruk.

Saya merasa kerangka kerja tidak menggunakan alat intinya secara maksimal. Misalnya, deklarasi TypeScript tidak sepenuhnya idiomatis dan dipenuhi dengan any dan any[] . Mereka juga mengabaikan fitur bahasa canggih yang meningkatkan kegunaan dan kemampuan alat API. Mereka juga mengandung hal-hal yang menjijikkan seperti export declare type Type = Function .

Menariknya, tampaknya cukup banyak keputusan yang ternyata terkait dengan Dart. Dart bukanlah sesuatu yang dipedulikan oleh sebagian besar pengguna Angular. Ini memiliki gagasan yang sangat berbeda tentang jenis apa dan bagaimana mereka digunakan dibandingkan dengan TypeScript. Dart <-> Interop JavaScript sering kali non-starter.

@aluanhaddad , implementasi dart telah bercabang menjadi proyek terpisah baru-baru ini, jadi semoga beberapa kekhawatiran Anda akan segera teratasi.

Perubahan ini telah menambahkan tingkat kerumitan yang signifikan, baik dalam hal LOC keseluruhan dan pemodelan mental dari dependensi komponen. File komponen saya sedikit lebih bersih tetapi dengan mengorbankan definisi ketergantungan eksplisit dan di tempat dan dilengkapi dengan penambahan file .module perasaan yang berlebihan.

Mengurangi boilerplate terdengar seperti hal yang baik tetapi saya berpendapat bahwa itu bisa berlebihan. Selanjutnya, tampaknya upaya pengurangan boilerplate khusus ini lebih baik digambarkan sebagai pergerakan boiler-plate sebagai lawan dari pengurangan langsung.

Saya pikir sudut cenderung ke arah yang lebih sulit dan memulai cepat yang kompleks. Sudah ada cukup banyak yang harus ditangani dalam hal pengaturan toolchain dan daftar file dan hal-hal yang harus dipahami (jika seseorang ingin mematuhi praktik terbaik) bahkan untuk aplikasi paling barebone pun sedang berkembang.

. @jbalbes terima kasih, senang mendengarnya.

@radusuciu Anda benar sekali, ini bukan pengurangan boilerplate tetapi pemindahan boilerplate itu ke area lain dari aplikasi. Seperti yang telah dikatakan oleh orang lain di sini tidak ada konflik antara pelingkupan tingkat komponen dan pelingkupan tingkat NGModul. Yang kami butuhkan adalah pelingkupan granular sehingga kami dapat memilih komponen, arahan, pipa, dan layanan mana yang harus tersedia untuk mengurangi robekan aplikasi berdasarkan penggunaan dan semantik khusus aplikasi mereka.

Tidak mengherankan bagi saya bahwa modul menambah kompleksitas nilai nyata yang meragukan bagi pembuat aplikasi. Mereka bukan bagian dari desain asli dan tampak seperti tambahan terlambat hanya ditambahkan karena hal-hal lain menabrak dinding dan tidak dapat dibuat untuk bekerja (malas memuat, kompilasi dll...) tanpa perubahan besar lain yang dibuat.

Saya tidak berpikir semua implikasi untuk pengembangan aplikasi vs "membuat fitur lain yang dijanjikan berfungsi" adalah agenda yang tinggi ketika ditambahkan tetapi karena semakin banyak aplikasi yang dikonversi ke RC5, mereka mulai menjadi lebih jelas.

Saya bahkan belum mulai mencoba mengonversi aplikasi saya ke modul, itu mungkin akan mati di RC4. Saya tahu begitu banyak bagian yang perlu dikerjakan ulang sepenuhnya dan semua yang saya dapatkan untuk semua upaya itu adalah menjadi lebih dekat dengan perubahan terobosan berikutnya RC dengan bundel runtime yang lebih besar karena minifikasi, tentu saja sesuatu yang sangat mendasar dan mendasar, rusak . RC seharusnya menjadi lebih stabil dan merasa lebih selesai saat mereka maju, ini tidak.

Gang, NgModule menjengkelkan seperti yang dijelaskan banyak orang dengan fasih. Tapi secara praktis itu bukan hal yang besar. Di sini (Oasis Digital / Angular Boot Camp) kami telah memperbarui banyak hal kecil, dan beberapa yang tidak terlalu kecil, ke RC5, dan itu dilakukan dalam waktu singkat (setelah lama belajar dan memahami).

Aplikasi setiap orang akan terpengaruh secara berbeda. Selain itu, saya pikir sikap Anda terhadap churn dan perubahan di Angular 2 mungkin akan berbeda jika Anda berfokus pada pengiriman aplikasi vs jika Anda juga menjual pelatihan dan dukungan untuk Angular 2. Bagi saya, semua pekerjaan untuk meningkatkan ke RC5 akan benar-benar mati dan usaha yang sia-sia - itu benar-benar akan memberikan manfaat negatif (bundel yang lebih besar) sehingga sulit untuk dibenarkan.

Hanya berpikir saya akan memberikan pemikiran saya keluar dari sisi lain dari dorongan lima hari pada platform kami untuk sampai ke RC6* (kami berada di nightlies, RC6 secara teknis belum turun pada saat penulisan). Saya merasa bahwa sementara komentar asli saya masih valid, ada perasaan lega karena telah mencapai tonggak sejarah ini. Perjuangan terbesar terus menggunakan sintaks perutean baru - terlalu banyak aturan path: '' kosong! (Saya ngelantur) tapi itu adalah sesuatu yang mungkin akan kita abstraksi.

Untuk NgModules di nightlies saya harus mengatakan pesan kesalahan semakin baik membuat seluruh proses sedikit lebih mudah untuk dikerjakan. Komponen dan Arahan biasanya dipanggil ketika mereka tidak dikonfigurasi dengan benar dengan informasi yang cukup sehingga Anda tidak berjalan di pohon ketergantungan NgModule yang besar untuk menemukan masalah. Masalah utama yang kami hadapi sekarang hanyalah fungsionalitas yang hilang pada halaman tanpa pesan kesalahan yang jelas. Ini biasanya karena komponen tidak dideklarasikan atau diimpor/diekspor dengan benar. Ini sedikit rumit tetapi dengan pendidikan itu cukup mudah untuk ditangani. Pengujian sekarang adalah dorongan kami berikutnya, benar-benar mati di dalam air. Tapi seperti fungsi push, kita akan sampai di sana pada akhirnya.

Kami mengambil napas dalam-dalam, melakukan sesuatu yang lain selama beberapa hari dan kemudian menghancurkannya. Kami berpegangan erat untuk perjalanan berikutnya, apa pun itu! Semoga sukses untuk semua orang yang terkena dampak ini dalam cara kecil atau besar. Alangkah baiknya jika ada semacam dialog dari tim Angular yang satu ini, Masalah tersulit yang kami hadapi adalah kurangnya komunikasi. Kami masih tidak tahu apa yang ada di kartu untuk catatan pertemuan NgModules minggu lalu tidak memberikan wawasan. Mari kita lihat apa yang terjadi minggu ini!

@SaltyDH Saya pikir ini adalah umpan balik yang berharga.
Saya pikir keluhan tentang komunikasi tidak benar-benar tepat.

Orang-orang implementasi membangun rilis baru dan orang-orang dokumen memperbarui dokumen.
Dokumen biasanya agak ketinggalan karena alasan yang jelas, karena mereka hanya dapat mendokumentasikan setelah dikodekan. Menulis dokumen juga merupakan pekerjaan yang sulit dan memakan waktu.

Jika Anda beralih ke rilis berikutnya pada hari dirilis atau bahkan menggunakan nightlies, agak tidak adil untuk mengeluh bahwa belum semuanya dikomunikasikan.
Tim Angular juga tidak dapat mengetahui sebelumnya apa yang mungkin menyebabkan kesulitan bagi pengguna dalam semua kasus.

Selalu ada anggota tim Angular yang memberikan dukungan pada Gitter dan masalah.
Anda juga harus menyadari bahwa beban komunikasi cukup asimetris, dengan beberapa anggota tim Angular hingga ribuan pengembang.

Saya sepenuhnya setuju bahwa ini lebih mudah pada master build (hampir RC6) dengan tahun terakhir+ penghentian akhirnya akan hilang.

@kylecordes dengan cara apa lebih mudah digunakan di master?

Dokumen desain untuk NgModules (sebelumnya dikenal sebagai AppModules saat dokumen desain ditulis) dirilis lebih dari sebulan yang lalu sebelum RC5 dirilis, dan saya agak siap untuk itu.
Selain itu, Karena NgModule adalah konsep yang lebih baru, sulit untuk mengambilnya sepenuhnya dan memigrasikan Aplikasi sedang ke besar.
Apa yang saya lakukan sebagai gantinya adalah, pertama-tama pahami sepenuhnya nuansa NgModules dan Cara berpikir dalam NgModules untuk merancang Aplikasi Angular 2. Kemudian dibuat aplikasi belajar mandiri dengan aplikasi NgModules.
Langkah kedua adalah - pikirkan bagaimana aplikasi saat ini dapat dipecah dalam modul dan kemudian memigrasikannya dari atas ke bawah. membuat satu Modul pada satu waktu dimulai dengan AppModule. Ini sangat membantu dan Aplikasi akhir terlihat lebih teratur.
image

Dan ya, Gitter sangat membantu dalam memberikan bantuan di NgModule bahkan sebelum RC5 dirilis. Posting RC5 kami memiliki dokumen dan blog yang tersedia untuk kami pelajari dengan lebih baik.

@zoechi Tanpa terlalu menggagalkan diskusi ini, saya merasa harus mengklarifikasi komentar saya. Saya tidak merujuk ke dokumentasi sama sekali, sebagian besar pemahaman saya berasal dari meninjau komit dan masalah di sini di GitHub, saya setuju dengan itu. Frustrasi saya datang dari kurangnya representasi di sini dalam masalah ini, kami berada di 61 komentar dan terus bertambah. Sederhana, "Kami menyadari kekhawatiran semua orang di sini dalam masalah ini, kami benar-benar percaya ini adalah pendekatan terbaik untuk Angular 2 dan kami menyadari kesulitan yang akan ditimbulkannya tetapi ini lebih baik untuk masa depan produk". Gitter bagus, tetapi pesan individu sering hilang di lautan orang yang mencoba memahami berbagai aspek Angular 2. Saya memang menjangkau melalui media ini tetapi karena perbedaan zona waktu atau prioritas lainnya, saya tidak bisa mendapatkan umpan balik resmi. dapat digunakan untuk membuat keputusan yang tepat. Apa yang membantu adalah Petualangan ini dalam podcast sudut https://devchat.tv/adv-in-angular/106-aia-angular2-rc5-and-beyond. Ini memberi saya kepercayaan diri untuk maju dengan peningkatan NgModule.

Semua yang terbaik.

Terima kasih atas umpan balik semuanya, maaf butuh waktu lama untuk mendapatkan balasan - kami sangat sibuk selama seminggu terakhir (memigrasikan aplikasi Google internal ke NgModules, jadi kami juga merasakan kesulitan refactoring)

Biarkan saya melihat apakah saya dapat menjernihkan beberapa pertanyaan dan kesalahpahaman di sini.

Hal pertama yang harus dipahami tentang @NgModule() (dan @Component dan dekorator Angukar lainnya) adalah bahwa mereka murni mengkompilasi konstruksi waktu - mereka ada untuk memungkinkan kompiler sudut menemukan grafik ketergantungan dalam aplikasi.

Versi (yang disederhanakan) dari penampilan dekorator kami:

//simplified Component decorator
export function Component(componentConfig){
  return function(componentClass){
    Reflect.defineMetadata('annotations', componentConfig, componentClass);
  }
}

Mereka tidak mengubah atau memodifikasi perilaku kelas yang didekorasi dengan cara apa pun - mereka hanya melampirkan beberapa metadata. Angular menggunakan metadata itu untuk membangun aplikasi Anda dan mengkompilasi template.

Dalam mode JiT, ini terjadi "Just in Time" - di antara Anda memanggil bootstrapModule dan rendering komponen pertama Anda, kompiler Angular mengambil metadata yang dilampirkan ke kelas menggunakan Reflect API:

let metadata = Reflect.getOwnMetadata('annotations', componentClass);

Namun, dalam mode AoT, ini bekerja sedikit berbeda - pada waktu pembuatan, kami _statis_ (yaitu, tanpa mengeksekusi kode Anda) mengekstrak metadata yang sama dari kode sumber dengan memindai dekorator.

Ini berfungsi dengan baik ketika Anda mem-bootstrap satu komponen, tetapi kami telah mendengar banyak umpan balik dari pengembang yang melakukan hal-hal yang lebih kompleks - mem-bootstrap beberapa komponen root, atau mem-bootstrap komponen yang berbeda berdasarkan status autentikasi, dll.

Jadi sementara dekorator @Component memberi kami kemampuan untuk menganalisis Komponen secara statis, kami tidak memiliki kemampuan untuk menganalisis _Application_ secara statis dan andal

Hal-hal yang berada di bawah payung "aplikasi"

  • PLATFORM_DIRECTIVES/PIPE/PROVIDERS
  • hal-hal yang sebelumnya Anda tambahkan ke bootstrap()
  • pengaturan tingkat kompiler
  • beberapa komponen root
  • penggunaan sisi server.

NgModules memperkenalkan gagasan tentang serangkaian fitur yang dapat dianalisis secara statis. Yang menarik adalah bahwa dalam mode kompilasi AoT, kami menganalisis modul root Anda, dan _menghasilkan_ ModuleFactory untuk setiap Modul dalam aplikasi - ini adalah versi modul yang telah dikompilasi sebelumnya, yang berisi _hanya_ pabrik yang Anda rujuk secara statis dalam template dan yang Anda tandai sebagai "entryComponents"

Karena kami telah mengekstrak informasi yang diperlukan untuk kompilasi Ahead-of-Time, kami sebenarnya dapat menggoyang dekorator (ngc akan menangani ini secara otomatis untuk final) - dan daripada menggabungkan aplikasi Anda mulai dari Modul root Anda, Anda mulai di root Module_Factory_ yang Anda buat, yang hanya berisi kode yang benar-benar digunakan dalam aplikasi Anda, jadi Anda tidak membayar penalti untuk modularitas, dan alat seperti rollup dan webpack2 dapat bekerja _lebih_ efisien

lebih banyak untuk mengikuti di balasan berikutnya ...

@robwormald Saya tidak bisa memasukkan emoji jumlah penghargaan untuk informasi latar belakang semacam ini.

Terima kasih!

Masalah lain yang kami hadapi yang dipecahkan oleh NgModules:

Pertimbangkan kasus di mana Anda ingin membangun DialogService atau yang serupa.

Secara historis, Anda akan melakukan sesuatu seperti:

@Injectable()
export class MyDialogService {
  //inject the dynamic compiler 
  constructor(private componentResolver:ComponentResolver){}

  //accept a component and a viewContainerRef
  showDialog(component:Type, target:ViewContainerRef){
    //compile the component into a factory, async
    return this.componentResolver.resolveComponent(component)
      .then(componentFactory => {
         //dynamically insert the compiled componentFactory into the view:
        return target.createComponent(componentFactory);
      })
  }
}

... yang akan Anda gunakan seperti

myDialogService.showDialog(MyRandomDialogComponent).then(...)

Hal-hal yang perlu diperhatikan di sini -

  • kompilasi komponen dalam mode JiT _harus_ asinkron, karena templateUrls dan styleUrls eksternal
  • a viewContainer menerima _componentFactory_ - jadi sekarang kode Anda bermasalah: Anda juga harus menulis ulang kode untuk beralih mode (antara JiT dan AoT), _atau_ Anda harus selalu menganggap API penyisipan komponen tidak sinkron. Ini mungkin baik-baik saja dalam kasus dialog, tetapi jika Anda sedang membangun UI kompleks secara dinamis (pikirkan Dasbor atau Tampilan Kotak atau apa pun), Anda dikenakan banyak penjadwalan Janji yang tidak perlu.
  • Layanan/komponen pihak ketiga atau bersama (seperti SharedDialogService) memiliki masalah yang sama, harus menerima _either_ Components atau ComponentFactories

Masalah ini muncul untuk aplikasi _any_ yang melakukan penyisipan komponen dinamis (yang tidak berarti pemuatan lambat) - dialog, router, dll, semua berharap untuk berinteraksi dengan ComponentTypes (kelas) alih-alih pemilih (foo-bar).

Jadi, ketika Anda menambahkan Component ke array entryComponents Anda di dekorator NgModule:

@NgModule({
  declarations: [ MyRandomDialogComponent ],
  entryComponents: [ MyRandomDialogComponent ]  
})
export class MyApp {}

Apa yang dikatakan ini kepada kompiler adalah "buatkan saya pemetaan antara MyRandomDialogComponent dan MyRandomDialogComponentNgFactory yang dikompilasi", dan _simpan di NgModuleFactory di mana ia dideklarasikan_

Dengan demikian, versi yang digerakkan oleh NgModule dari dialogService di atas terlihat seperti:

@Injectable()
export class MyDialogService {
  //inject the component factory resolver 
  constructor(private componentFactoryResolver:ComponentFactoryResolver){}

  //accept a component and a viewContainerRef
  showDialog(component:Type, target:ViewContainerRef){
    //*retrieve* the componentFactory by component, sync
   let componentFactory = this.componentFactoryResolver.resolveComponentFactory(component)
   //add the componentFactory to the view, sync
   return target.createComponent(componentFactory);
  }
}

Sekarang, Komponen apa pun yang Anda tambahkan ke entryModules dapat diambil secara serempak dan dimasukkan secara dinamis ke dalam tampilan, dan kode Anda _tidak_ harus berubah tergantung pada mode apa yang Anda gunakan, juga pihak ke-3/pustaka bersama tidak perlu khawatir tentang kompilasi logika.

Terima kasih atas penjelasannya @robwormald

Satu pertanyaan adalah: apakah itu memerlukan penghapusan deklarasi arahan/pipa? Apakah ada alasan mengapa mereka tidak bisa hidup berdampingan dengan NgModule?

Saya merasa orang-orang, termasuk saya sendiri, frustrasi bukan pada NgModule "anak baru di blok" atau kesalahpahaman apa pun tentangnya, tetapi karena "cara lama" dalam melakukan sesuatu, yang tampaknya _berfungsi dengan baik_ dengan banyak orang, sedang dipindahkan secara paksa, terutama pada tahap RC akhir ini. Saya pikir ini adalah perbedaan penting dari resistensi apa pun terhadap NgModule itu sendiri, yang belum banyak saya lihat, yang belum ditangani secara langsung.

Saya juga melihat bahwa permintaan tarik untuk menghapus deklarasi directive/pipe sudah habis (https://github.com/angular/angular/pull/10912) - Saya berharap kita bisa mendapatkan respons tentang hal ini sebelum ada yang diatur batu.

Terima kasih sebelumnya. Tidak diragukan lagi, Angular sangat menyenangkan untuk diajak bekerja sama dan saya sangat menghargai kerja keras tim selama setahun terakhir+

Ada beberapa komentar di sini mengenai "lingkup global" - ini salah memahami mekanisme kompiler dan modul (yang sepenuhnya dapat dimengerti, ini adalah hal yang rumit).

Membuang seluruh aplikasi Anda ke dalam satu NgModule adalah "baik" dengan cara membuang seluruh status aplikasi Anda ke $rootScope adalah "baik" di Angular1 (baca: berfungsi, tetapi desain aplikasinya buruk)

Di Angular 1, membawa modul ke dalam aplikasi kurang lebih "mencemari" seluruh aplikasi Anda, karena semuanya dibuang ke dalam satu tas injektor.

Di Angular2, NgModues memiliki beberapa mekanisme pelingkupan yang sangat kuat yang memungkinkan komposisi tanpa polusi. Sekali lagi, itu kembali ke kompiler.

Saat Angular melintasi dan mengkompilasi Aplikasi Anda, setiap komponen yang ditemuinya _dikompilasi dalam konteks di mana ia dideklarasikan_

Misalnya - bayangkan Anda memiliki SharedModule dengan beberapa fungsi yang ingin Anda bagikan ke seluruh aplikasi

@Component({
  selector: 'shared-component-one',
  template: `
    <div>Shared Component One</div>
    <shared-component-two>
  `
})
export class SharedComponentOne {}

@Component({
  selector: 'shared-component-two',
  template: `
    <div>Shared Component Two</div>
  `
})
export class SharedComponentTwo {}

@NgModule({
  declarations: [ SharedComponentOne, SharedComponentTwo ],
  exports: [ SharedComponentOne ]
})
export class SharedModule {}

Baik SharedComponentOne dan SharedComponentTwo _dideklarasikan_ di SharedModule - deklarasi menyiratkan _ownership_ - jadi kedua Komponen ini dimiliki oleh SharedModule. Namun, _only_ SharedComponentOne _diekspor_ dari modul - SharedComponentTwo tetap _private_ ke SharedModule.

Jika Anda membawa SharedModule dan menggunakannya di modul lain, seperti:

@Component({
  selector: 'some-component',
  template: `
    <div>hello from some component</div>
    <shared-component-one></shared-component-one>
  `
})
export class SomeComponent {}

@NgModule({
  imports: [ SharedModule ],
  declarations: [ SomeComponent ]
})
export class SomeModule {}

...ketika kompiler mulai mengompilasi SomeComponent , ia menemukan selektor shared-component-one , dan karena SharedModule (yang mengekspor SharedComponentOne ) diimpor ke SomeModule , ia mengetahui bahwa shared-component-one === SharedComponentOne.

Menariknya, ketika kompiler benar-benar mengkompilasi SharedComponentOne, ia melakukannya "di dalam" SharedModule, yang memungkinkannya untuk menggunakan hal-hal di dalam SharedModule yang tidak terpapar ke dunia luar.

Ini sangat mirip dengan cara kerjanya dengan Component.directives, dan dalam hal ini keduanya sama.

Pertimbangkan jika Anda memiliki sesuatu seperti fitur Tab:

@Component({
  selector: 'my-tabs',
  template: '...'
})
export class TabsComponent {}

@Component({
  selector: 'my-tab',
  template: '...'
})
export class TabComponent {}

Kedua komponen ini adalah tingkat atas, tidak ada hubungan hierarkis yang dapat diandalkan. Ini menyebabkan ledakan semacam konvensi yang dilakukan orang

export const TAB_DIRECTIVES = [ TabsComponent, TabComponent ]

Fitur Tab yang lebih rumit mungkin memiliki layanan yang mengelola beberapa contoh tab, jadi Anda juga harus menangani kasus itu...

export const TAB_PROVIDERS = [ ... ]

dan menggunakannya menjadi latihan dalam mengingat semua hal yang Anda harus ekspor dan impor ...

import {TAB_DIRECTIVES, TAB_PROVIDERS}

dan kemudian menyediakan semua hal itu di lokasi yang tepat _di mana pun_ Anda ingin menggunakannya. Juga sangat mudah pada titik ini untuk lupa mengimpor SEMUA hal yang Anda butuhkan untuk sebuah fitur dan berakhir dengan kegagalan diam yang aneh, atau komponen yang dikompilasi tanpa semua konteks yang diperlukan.

Dengan NgModule, Anda cukup mengemasnya menjadi satu unit, dan menyebarkannya ke aplikasi Anda, dan mengimpornya jika relevan.

Untuk pustaka seperti Desain Material, yang mungkin memiliki sejumlah fitur yang tersebar di beberapa modul, Anda dapat memanfaatkan semantik impor/ekspor yang sama untuk membuatnya lebih portabel:

@NgModule({
  exports: [ TabsModule, NavbarModule ]
})
export class MaterialSharedModule {}

menarik modul tunggal itu memungkinkan semua aplikasi Anda menggunakan komponen, dan sekali lagi, pada waktu AoT, hanya komponen yang Anda gunakan yang akan diimpor ke kode yang dihasilkan.

Mengenai mengapa kami menghapus Component.directives / pipa, kami telah mendengar banyak umpan balik di kedua arah. Kami merasa memiliki dua cara untuk menyelesaikan hal yang sama umumnya merupakan pola yang buruk, jadi kami membuat pilihan untuk memungkinkan orang menulis lebih sedikit kode secara umum, dan mereka yang menginginkan pelingkupan eksplisit yang sebelumnya ditawarkan oleh Component.directives dapat menyelesaikan fungsionalitas _same_ dengan pelingkupan di tingkat modul.

Di RC5, kami melakukan semacam pengangkatan otomatis Component.directive ke dalam lingkup "global". Ini adalah upaya untuk memperlancar transisi, dan meskipun berhasil bagi kebanyakan orang, perilaku lama dan baru yang bercampur menyebabkan beberapa kesalahan dan perilaku aneh yang sementara membuat frustrasi, bersifat sementara. Ini hilang di RC6 (dan pesan kesalahan telah ditingkatkan)

Mengapa ini berubah begitu terlambat dalam permainan - kami hanya bisa meminta maaf. Kami tidak suka membuat perubahan menit terakhir seperti yang Anda lakukan. Pada akhirnya, kami benar-benar membangun kerangka kerja dengan cara yang belum pernah dilakukan di front end land sebelumnya, dan dengan demikian kami akan mengalami masalah yang tidak terduga dan masalah desain. Ini adalah salah satu dari kasus tersebut, dan hal ini sangat diperdebatkan dan diselidiki di antara tim inti sebelum kami membuat keputusan. Sekali lagi, kami mohon maaf atas masalah ini, tetapi kami yakin hasil akhirnya adalah cara yang lebih baik untuk membangun _applications_, itulah sebabnya kami semua ada di sini.

Terima kasih atas kesabaran semua orang. Saya akan membiarkan ini terbuka jika ada pertanyaan lain yang belum saya bahas di sini.

rampok

Kerja bagus, @robwormald

Saya ingin menambahkan beberapa pengamatan lagi:

Penyedia

Rob berfokus pada _deklarasi_, _import_, dan _ekspor_. Modul _Providers_ berbeda.

@Component.providers hidup! Hanya @Component.directives dan @Component.pipes yang akan dihapus.

Anda dapat menggunakan @NgModules.providers dan @Component.providers . Mereka memiliki tujuan yang berbeda:

a) @NgModules.providers _memperluas_ aplikasi dengan menambahkan penyedia ke injektor "utama" (injektor root aplikasi untuk modul yang dimuat dengan penuh semangat). Beginilah cara RouterModule menambahkan layanan perutean ke aplikasi Anda tanpa Anda harus menyediakannya.

b) @Component.providers _enkapsulasi_ penyediaan layanan dalam lingkup instance komponen (dan sub-pohon komponennya).

Kedua pendekatan memenuhi kebutuhan yang berbeda.

Saran umum saya: _jika Anda memiliki penyedia di @Component hari ini, tinggalkan saja_

Modul Fitur

Mereka adalah cara yang ampuh untuk mengatur aplikasi Anda. Bab Modul Sudut memiliki bagian singkat tentang pemfaktoran ulang dari Modul Sudut monolitik ke modul fitur . Ini cukup mudah (setidaknya bagi saya beberapa kali saya melakukannya.).

Saya mencari jahitan alami di aplikasi saya. Aku tidak gila. Saya tidak memodulasi setiap komponen.

Alasan Desain Material tampaknya melakukannya adalah karena mereka mencoba mempermudah kita untuk menggunakan apa yang kita inginkan dengan cara yang halus.

Mereka akan memiliki modul wastafel dapur yang hanya mengekspor kembali semuanya. Anda bisa mengimpornya dan selesai. Tetapi jika saya menyetel aplikasi saya sendiri, saya membuat _re-exporting module_ serupa yang mengekspor hanya bagian MD yang saya inginkan.

Ini adalah pola yang dapat diikuti oleh vendor perpustakaan mana pun dan mungkin masuk akal di perusahaan tempat kami mengumpulkan "kit" gadget yang disetujui perusahaan kami sendiri.

Menemukan dependensi deklarasi

Kompiler melakukan pekerjaan yang jauh lebih baik sekarang untuk memberi tahu Anda ketika ada sesuatu yang hilang. Jika Anda mengikuti praktik yang disarankan dan _always, always, always, always hyphenate_ nama pemilih komponen Anda, kompiler akan memberi tahu Anda saat Anda memiliki komponen yang tidak dideklarasikan. Itu juga mengambil binding dan arahan data yang tidak dideklarasikan/tidak dikenali.

Bermigrasi dari pra-RC5 memang meningkatkan rasa kehilangan. Kita harus melakukan pekerjaan yang membosankan untuk menemukan dependensi dalam directives dan pipes kita sebelumnya. Dan kita harus de-dupe. Ini adalah ketidaknyamanan esensial hidup di tepi.

RC seharusnya tidak banyak berubah

Ya. Anda tidak akan mendapatkan argumen dari tim tentang itu. Itu tidak disengaja. Seandainya kami tahu kami membutuhkan NgModule , kami akan memilikinya dalam versi beta.

Tapi IMO, lebih baik mengirimkan produk yang tepat daripada mengikuti beberapa gagasan tentang apa yang seharusnya menjadi RC dan mengirimkan produk yang salah. Juga ... dan tidak nyaman untuk mengatakannya ... tetapi jika Anda telah menonton beberapa perusahaan perangkat lunak besar baru-baru ini, Anda mungkin telah memperhatikan gagasan yang sama fleksibelnya tentang "kandidat rilis". Itulah cara industri kami berjalan karena suatu alasan.

Saya telah mengonversi sejumlah aplikasi sekarang dan membantu orang lain melakukannya. Setelah melewati fase "_mereka memindahkan keju saya (lagi)_", ini adalah migrasi yang cukup mekanis dan semua orang tampaknya berpikir bahwa mereka berada di tempat yang lebih baik. Mungkin mereka hanya bersikap baik padaku. OTOH, saya tidak bergaul dengan orang-orang yang baik-baik saja ;-)

(juga, re: nama)
Kami bikeshed nama sampai mati. Mereka awalnya disebut AppModules (karena mereka menggambarkan sesuatu yang tingkatnya lebih tinggi dari sebuah komponen, sebuah "Aplikasi") tapi itu bukan istilah yang cukup luas. Paket, bundel, barel, gumpalan, dll.

Perlu diingat bahwa ini bukan pengganti modul ES - ini adalah augmentasi yang akan membuat pohon gemetar dan modul ES bekerja lebih baik untuk semua pengembang sudut, dan secara semantik, mereka mirip dengan cara kerja modul ES (impor, ekspor, deklarasi)

Jadi, penamaan itu sulit. NgModul itu.

Kami menyelesaikan API untuk 2.0.0, jadi kami akan mengawasi beberapa bulan ke depan setelah rilis untuk melihat pola apa yang berkembang, dan di mana kami dapat menambahkan dan membuat kesimpulan yang lebih baik untuk 2.1.

Terima kasih dengan tulus @robwormald @wardbell atas komentar yang sangat berwawasan. Saya pikir bagi saya kelegaan terbesar adalah

"Kami menyelesaikan API untuk 2.0.0, jadi kami akan mengawasi beberapa bulan ke depan setelah rilis untuk melihat pola apa yang berkembang, dan di mana kami dapat menambahkan dan membuat kesimpulan yang lebih baik untuk 2.1."

Ini adalah sesuatu yang telah kami dengar beberapa minggu yang lalu tetapi sekarang secara khusus dalam konteks NgModules bersama dengan semua umpan balik ini. Ini adalah kepercayaan diri yang saya butuhkan untuk pergi ke Dewan dan berkata. Kita sudah selesai di sini, saatnya untuk menyelesaikan pembuatan aplikasi kita. Saya juga ingin menyampaikan selamat kepada seluruh tim dan komunitas ng2 atas pencapaian ini! Saat-saat yang menyenangkan di depan.

Sejujurnya saya percaya Anda bisa mengatakan itu @SaltyDH. Churn Angular 2 telah berakhir.

Itu tidak berarti Angular 2 selesai berevolusi. Akan ada rilis mendatang. Tapi churn yang mengarah ke 2.0 ... sudah ... berakhir!

Terima kasih banyak atas kejujuran dan kasus penggunaan eksplisitnya, kawan. Ini sangat membantu.

Hanya pemikiran singkat tentang penamaan dan duplikasi di API untuk NgModule, yang menurut saya agak merepotkan.

IMO ini:

@NgModule({
  declarations: [ SharedComponentOne, SharedComponentTwo ],
  exports: [ SharedComponentOne ]
})
export class SharedModule {}

...bisa lebih jelas dan lebih ringkas sebagai:

@NgModule({
  private: [ SharedComponentTwo ],
  public: [ SharedComponentOne ]
})
export class SharedModule {}

1) WRT untuk penamaan (publik dan pribadi vs deklarasi dan ekspor), pada dasarnya bagaimana @robwormald di atas dan saya yakin banyak orang lain yang menjelaskannya

2) (Mengabaikan penamaan) mengapa SharedComponentOne perlu diulang? Pasti bisa dibilang kalau itu "ekspor" pasti "deklarasi", jadi bisa didesugasi begitu saja?

Hanya dua sen saya untuk sesuatu yang sangat subjektif - sekali lagi terima kasih atas penjelasan rincinya!

@robwormald @wardbell Terima kasih atas penjelasan detailnya.

Dan seperti yang saya katakan sebelumnya di utas ini NgModules membantu kami mengatur lebih baik. Contoh terbaru adalah membuat Arahan Validator untuk formulir yang didorong oleh templat. Sebelum RC5 kami harus mengimpor setiap arahan pada komponen tempat kami membuat formulir. Sekarang kita hanya mengemasnya dalam VaildatorModule dan mengimpor Modul di mana pun diperlukan. Validator apa pun yang kami tambahkan nanti, secara otomatis tersedia untuk modul tempat saya mengimpor ValidatorModule . Saya hanya perlu memperbarui template tanpa mengkhawatirkan ketergantungan.

@JamesHenry declarations , imports dan exports digunakan untuk menjaga NgModules sejalan dengan modul ES6 seperti kita import , export dan declare barang dalam modul ES6.
Saya setuju dengan sugaring, hal-hal yang diekspor dapat dihilangkan gulanya menjadi deklarasi otomatis secara ajaib.

@JamesHenry

1), kami terjebak dengan impor/ekspor karena model mental lebih dekat dengan cara kerja modul es (setidaknya dalam hal pelingkupan) - Anda mendeklarasikan sesuatu dalam modul, mengimpor sesuatu dari modul lain, dan mengekspor sesuatu agar tersedia untuk yang lain.

2) if it is an "export" it must be a declaration, so it could just be desugared that way? -> ini berfungsi sampai Anda menggunakan ngModule untuk mengekspor ulang, seperti pada contoh MaterialModule di atas - ada banyak kasus di mana Anda dapat menggunakan ngModule untuk mengekspor ulang sesuatu yang dideklarasikan di modul lain, dan maka kesimpulan semacam berantakan.

@robwormald Komentar yang bagus! pasti layak posting blog.

Saya memiliki perpustakaan dialog yang menggunakan @NgModule sekarang dan saya dapat mengatakan bahwa saya melihat pengguna berjuang ketika mencoba menambahkan komponen khusus karena mereka lupa mendaftarkannya di entryComponents , ini tampaknya tidak cukup jelas tetapi dapat dimengerti karena ini adalah fitur lanjutan...

Saya yakin itu akan tenggelam seiring waktu

@shlomiassaf terima kasih!

Harus disebutkan juga, untuk kasus seperti milik Anda:

Perhatikan bahwa ketika Anda menggunakan router angular, Anda menambahkan komponen ke deklarasi dan konfigurasi rute, tetapi _not_ ke entryComponents, meskipun faktanya router adalah definisi dari entryComponents. (ingat - entryComponent === hal yang ingin Anda rujuk oleh Kelas, bukan pemilih)

Ada trik keren yang dapat dimanfaatkan oleh perpustakaan mana pun - ada token ajaib bernama ANALYZE_FOR_ENTRY_COMPONENTS - lihat https://github.com/angular/angular/blob/master/modules/%40angular/router/src/ router_module.ts#L117 untuk cara router menggunakannya.

Jadi untuk lib yang berhubungan dengan komponen yang dimasukkan secara dinamis, Anda dapat melakukan sesuatu seperti:

@NgModule({
  providers: [ DialogService ]
})
export class DialogModule {
  static withComponents(componentList): NgModuleWithProviders {
    return {
      ngModule: DialogModule,
      providers : [
         { provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: componentList, multi: true }
      ]
     }
  }
}

digunakan seperti

@NgModule({
  declarations: [ MyConfirmDialog, MyQuestionDialog ],
  imports: [
    DialogModule.withComponents([ MyConfirmDialog, MyQuestionDialog ])
  ]
})
export class MyAppModule {}

Mungkin berfungsi untuk kasus penggunaan Anda, mungkin tidak.

@JamesHenry Sangat penting bahwa declarations tidak bingung dengan private . Anda mengatakan _Modul ini mendeklarasikan komponen ini_. Anda tidak membuat pernyataan apa pun tentang publik atau pribadi. Anda membuat klaim kepemilikan.

Ini benar-benar seperti yang terjadi di modul ES6. Apa pun yang Anda definisikan di dalam file "milik" modul yang ditentukan oleh file itu. Apakah itu publik atau tidak tergantung pada penggunaan kata kunci Anda export .

Dan seperti modul ES6 Anda _dapat mengekspor kembali_ barang yang Anda impor.

Saya suka menganggap declarations sebagai "trik" yang membuat saya tidak perlu secara fisik menempatkan semua komponen, arahan, dan pipa saya dalam file fisik yang sama (seperti yang harus Anda lakukan dengan modul ES6 jika Anda mau semua kelas tersebut milik modul ES6 yang sama).

Jadi, bagi saya, declarations adalah pengganti untuk menempelkan file-file itu ke dalam satu file besar yang mengerikan. Itu adalah model mental _my_.

Satu hal yang perlu diperhatikan adalah perbedaan logis antara penyedia dan komponen dalam konteks modul.

Penyedia dan Komponen dideklarasikan di tempat yang sama ( NgModuleMetadataType ) sehingga pengembang mungkin secara intuitif merasa bahwa penyedia berperilaku seperti komponen... yang berpikir bahwa penyedia dalam modul akan menghasilkan instance untuk modul itu.. .

Karena penyedia dikelola oleh DI, ini tentu saja tidak benar, mereka sebenarnya adalah level aplikasi.
Komponen dalam modul bersifat pribadi jika tidak diekspor, hal ini dapat menyebabkan kebingungan.

Saya suka konsep modul, IMO satu-satunya masalah di API adalah memiliki penyedia dan komponen yang dideklarasikan di tempat yang sama di dalam modul ... untuk pendatang baru itu hal yang sulit untuk dipahami.

@wardbell Terima kasih Ward itu benar-benar hebat! Hanya untuk memperjelas karena ini baru saja muncul dalam diskusi, ketika kita mengatakan Angular 2 adalah API lengkap, ruang nama mana yang kita bicarakan di sini? @sudut/???

@robwormald Terima kasih! Tip yang bagus!!!
Yang rasa gula! akan menerapkan.

Saya bukan karyawan Google dan mungkin karyawan Google tidak bisa mengatakannya. Saya hanya dapat melaporkan apa yang saya lihat dengan kedua mata saya: pembekuan API yang sangat serius di seluruh kumpulan perpustakaan @angular/ .

Ada ide bagus yang disimpan di rak karena tidak cukup baik atau cukup dalam untuk membenarkan menahan rilis. Begitulah seharusnya. Ide bagus tidak pernah berhenti. Tetapi waktunya telah tiba untuk mengatakan _Ini adalah Angular 2.0_ Anda.

Kami memiliki janji penghapusan API usang yang akan datang antara sekarang dan "final". Itu memiliki tweak ... seperti yang bisa dilihat siapa pun dengan melihat master. Aku merasa kita sudah selesai.

@wardbell Saya menggemakan apa yang Anda katakan tentang ekspor.
Index.ts pernah diisi dengan

export * from 'a.component'
export * from 'b.component'
export * from 'c.component'
export * from 'p.directive'
export * from 'x.service'
export * from 'z.pipe'

sekarang dikurangi menjadi hanya export * from my.module
sisanya semua barang bersih duduk di ekspor NgModule sebagai
exports: [ AComponent, BComponent, CComponent, PDirective ] dan seterusnya

@wardbell Saya pikir @NgModules.providers seharusnya @NgModules.rootProviders atau @NgModules.appProviders .

Saya merasa itu dengan jelas menggambarkan konteks penyedia.

@shlomiassaf Itu akan menyesatkan. Efek @NgModules.providers berbeda untuk modul bersemangat dan malas. Modul yang dimuat lambat mendapatkan injektor anak mereka sendiri yang berarti bahwa _penyedia mereka_ ditambahkan ke injektor _child_, bukan injektor _root_. Dan begitulah jika seorang lazy memuat sebuah lazy memuat sebuah lazy.

Mungkin bisa saja ada nama yang berbeda. Anda tahu bagaimana yang terjadi. Tetapi rootProviders tidak akan menjadi peningkatan untuk alasan yang baru saja saya berikan.

@wardbell setuju, tidak memikirkan skenario itu.

Hanya ingin menambah sentimen bahwa balasan dan komunikasi yang menyeluruh sangat kami hargai. Jika ini memang yang terakhir dari rasa sakit tumbuh rc-to-final maka kita pergi ke balapan. Terima kasih!

Seperti yang dikatakan orang lain, umpan balik dari tim sangat dihargai. Namun, perubahan semacam ini selama fase pengembangan ini menunjukkan kesalahan desain mendasar.
Mari kita jujur ​​pada diri kita sendiri, kita semua pernah melakukan kesalahan semacam ini, jadi tidak ada gunanya menghakimi, tetapi ketika saya membuat kesalahan, itu membuat saya rendah hati, dan semoga membuat saya selanjutnya lebih bijaksana. Saya tidak mendapatkan kesan bahwa itu memiliki efek yang sama pada tim Anagular.

Saya suka menganggap deklarasi sebagai "trik" yang membuat saya tidak harus secara fisik menempatkan semua komponen, arahan, dan pipa saya dalam file fisik yang sama (seperti yang harus Anda lakukan dengan modul ES6 jika Anda menginginkan semua kelas tersebut untuk milik modul ES6 yang sama).

Jadi, bagi saya, deklarasi adalah pengganti untuk menempelkan file-file itu ke dalam satu file besar yang mengerikan. Itu model mental saya.

@wardbell Mungkin saya kehilangan sesuatu yang mendasar, tetapi saya tidak melihat bagaimana menggunakan NgModule.declarations secara fundamental berbeda dari mengimpor semua, tetapi hanya mengekspor kembali sebagian, dari ESModules Anda. Ironisnya, batasan utama ESModules adalah bahwa mereka hanya menyediakan konsep modul fisik, bukan yang logis. Saya tidak melihat bagaimana NgModule meningkatkan itu. Ini hanya sintaks agregasi yang berbeda tetapi tidak meningkatkan tingkat abstraksi ke tingkat yang berarti.

Juga, NgModules benar-benar gagal mengatasi masalah utama:

Seluruh pola Function[] buram dalam semua cara yang salah. Ini menurunkan kemampuan untuk ditemukan menjadi nol. Seseorang harus membaca sumbernya untuk menentukan apa yang ada dalam array penyedia. Hal yang sama berlaku untuk NgModule.exports .

Tapi IMO, lebih baik mengirimkan produk yang tepat daripada mengikuti beberapa gagasan tentang apa yang seharusnya menjadi RC dan mengirimkan produk yang salah. Juga ... dan tidak nyaman untuk mengatakannya ... tetapi jika Anda telah menonton beberapa perusahaan perangkat lunak besar baru-baru ini, Anda mungkin telah memperhatikan gagasan yang sama fleksibelnya tentang "kandidat rilis". Itulah cara industri kami berjalan karena suatu alasan.

@wardbell Frustrasi terbesar tentang RC bagi saya adalah kesan bahwa Beta baru saja didorong ke RC karena ng-conf dan google i/o. Untuk membuat kemajuan, alasannya harus dikemukakan dengan jelas: ini adalah _pemasaran_ dan sebagai teknolog kita harus melawan tren gagasan kedewasaan yang fleksibel ini. Anda mungkin tahu produsen mobil populer di lembah di mana diskusinya adalah tentang apakah benar menjual beta untuk suatu produk karena itu mungkin memakan waktu lama. Saya tidak ingin melebih-lebihkan, tetapi sebagai teknolog kita harus angkat bicara jika itu yang terjadi pada industri kita karena itu akan menuju ke arah yang salah.

Saya suka pendekatan ngmodule tapi saya punya pertanyaan @robwormald :

Saya memiliki layanan bersama yang tidak memiliki komponen, tidak ada arahan, dan tidak ada pipa. Ini hanya memiliki layanan ( forRoot ) dan berisi semua kelas model bisnis. app.module mengimpor ServerApiModule.forRoot() oleh karena itu layanan tersedia untuk seluruh aplikasi. Haruskah modul fitur, yang menggunakan layanan dan kelas model bisnis, mengimpor modul bersama ini? Secara teknis itu tidak perlu (tidak ada kesalahan) tetapi dari pandangan semantik itu masuk akal (juga tidak ada kesalahan). Apa yang harus kita lakukan dengan modul semacam itu? Impor mereka atau tidak? Saya pribadi menyukai kemungkinan kedua karena dikatakan 'Hei, saya adalah modul fitur dan saya membutuhkan layanan ini dan saya membutuhkan kelas model bisnis ini'.

Terima kasih atas jawaban!

Jadi saya bisa merasakan sakitnya dengan perpustakaan/perpustakaan aplikasi modular dan ngModule.

Tetapi seperti yang dikatakan berkali-kali, jangan mencampur dua cara yang mungkin. Itu dan akan membingungkan.

Jadi pendekatan yang benar adalah mendeklarasikan ngModule untuk setiap komponen.
Tetapi karena ini membuatnya lebih banyak pembuat kode boiler untuk setiap komponen, cara itu tidak berfungsi baik dalam skala besar.

Jadi sebaiknya tidak menambahkan dekorator baru yang disebut ComponentModule yang lebih atau kurang gula untuk menghindari mendeklarasikan komponen dan modul seperti materi yang harus dilakukan.

Dengan cara ini? Jika saya melihat komponen. Saya tahu itu HARUS menjadi bagian dari ngModule. Jika saya memiliki kasus untuk banyak komponen untuk menggabungkannya, saya BISA menggunakan NgModule. Jika saya hanya ingin komponen mandiri seperti "komponen lama" saya menggunakan ComponentModule dan saya TAHU semua dependensi dan itu bisa menjadi dependensi Modul untuk modul lain, tetapi bukan bagian dari mereka

@nathraQ jika pendekatan yang benar adalah menggunakan NgModule untuk setiap Komponen, dan mungkin saja demikian, maka NgModule seharusnya tidak diperkenalkan, dan Komponen seharusnya baru saja ditingkatkan. Mengenai boilerplate, Angular 2 sangat berat sehingga hampir tidak penting pada saat ini.

Banyak kerangka kerja yang tidak memiliki sistem modulnya sendiri telah berhasil menggunakan konvensi untuk menetapkan pola standar untuk tata letak dan visibilitas konstruksi. Seorang bijak pernah berkata bahwa Anda tidak dapat mendefinisikan konvensi setelah fakta; bahwa mereka harus berada di sana sejak awal. Saya skeptis terhadap klaim ini, tetapi bencana ini membuktikan bahwa dia benar.

@aluanhaddad maaf saya tidak setuju. Saya memiliki kasus penggunaan saya hanya untuk satu modul di 1.x sudut dengan manajemen ketergantungan khusus (seperti starter utas ini), tetapi saya juga memiliki kasus penggunaan untuk modul untuk menggabungkan satu set pengontrol, arahan, dan layanan.

Keduanya berguna. Sekarang kita harus mencari cara untuk mengintegrasikannya agar dapat dimengerti oleh semua orang

Wah, panjang sekali bacanya :smile:

Saya dapat melihat pro dan kontra dari perubahan baru, tetapi itu membuat saya berpikir tentang satu skenario yang saya alami masalah di Angular 1.

@wardbell @robwormald -

Jika saya menggunakan pola SharedModule, dan saya mengimpor dua perpustakaan pihak ke-3 (ui-bootsrap vs angular-strap siapa?) yang keduanya menggunakan pemilih yang sama untuk komponen, katakanlah my-selectbox

Saya akan mendapatkan kesalahan jika saya mencoba mengimpor keduanya? Baik?

Salah satu solusi yang saya baca di sini adalah mengekspor ulang salah satu perpustakaan dalam modul khusus
Tapi itu berarti saya harus terus memperbarui modul pembungkus setiap kali perpustakaan memutakhirkan bukan?

Juga, itu bisa terjadi saya memiliki pemilih komponen saya sendiri dengan nama yang sama (dan dalam proyek-proyek besar yang mungkin terjadi lebih dari sekali)

Apakah ada solusi yang direkomendasikan untuk masalah ini? atau itu "modul pembungkus"?
(Saya harap kami tidak akan kembali menggunakan awalan untuk penyeleksi, itu tidak menyenangkan)

Terima kasih sebelumnya!

Penspasian nama, atau awalan seperti yang disebut beberapa orang, umumnya merupakan ide yang bagus, tidak peduli seberapa besar proyek Anda. Ya, ini mungkin lebih sepele dalam proyek yang lebih kecil, tetapi segera setelah modul pihak ketiga terlibat, saya akan mengatakan itu hampir merupakan persyaratan — minimal itu memberikan ketenangan pikiran mengetahui bahwa tabrakan tidak akan terjadi bahkan ketika modul lain diperbarui , tetapi juga pengembang dapat dengan mudah mengidentifikasi apa yang menjadi milik setiap modul tanpa harus mengikuti pohon ketergantungan.

@nathraQ Semua pola ini dapat dicapai dengan modul ECMAScript. Pengenalan NgModule tidak membawa kita kemana-mana dan fakta bahwa perpustakaan seperti AngularMaterial mengubah Komponen menjadi NgModules hanya untuk mempertahankan enkapsulasi yang disediakan sebelumnya membuktikan maksudnya.

@aluanhaddad NgModules mencoba melakukan sesuatu yang sangat berbeda dari modul ES, dan juga tidak mengganti enkapsulasi Komponen, yaitu, baik modul ES maupun Komponen tidak mengubah tanggung jawab intinya. NgModules adalah media yang Anda gunakan untuk mendeskripsikan arsitektur di seluruh aplikasi Anda, dan ini membantu Angular lebih memahami maksud Anda dan mengoptimalkannya, memungkinkan hal-hal seperti mengkompilasi bagian tertentu dari aplikasi Anda sebelumnya, menyajikan modul yang diselesaikan secara dinamis dari server, dan seterusnya, semua yang tidak dapat dicapai dengan modul ES. Untuk alasan yang sama, satu NgModule per Komponen bukanlah aturan praktis yang harus diikuti.

Memang benar bahwa aplikasi yang lebih sederhana mungkin tidak mendapatkan banyak manfaat dari manfaat tersebut, tetapi dalam kasus tersebut NgModules seharusnya tidak terlalu "mengganggu".

@emilio-martinez , seperti yang ditulis @aluanhaddad , ES6 dan "sudut 2 cara lama" memberi kami namespace yang kami butuhkan.

Saya telah mengerjakan proyek yang sangat besar dengan Angular 1, memiliki pemilih bernama: mb-product-list dapat bertabrakan dengan sangat cepat dengan orang lain jika itu adalah proyek besar (Bahkan dalam tim yang terdiri dari 5+ pengembang).

Mencoba menyelesaikannya dengan lebih banyak namespace Anda berakhir dengan: mb-somefeature-product-list yang membuat template terlihat kotor.

Saya sangat senang melihatnya diselesaikan di ng2 karena metadata directives .
Anda dapat menginstal npm paket apa pun yang Anda suka, dan hanya mengimpor apa yang Anda butuhkan darinya per komponen.

ngModules memiliki manfaat yang pasti, ini membantu memuat potongan async dan juga membantu kami menulis lebih sedikit impor dan meningkatkan produktivitas.

Tetapi menggunakan pola SharedModule memperkenalkan namespace global, seperti yang kita miliki di ng1.

Setidaknya dengan penyedia, itu diberi namespace oleh token ES6, lokasi file.

Dengan komponen, karena selektor, akan berteriak bahwa ada dua komponen dengan selektor yang sama.

Saya berharap kami memiliki beberapa cara mudah untuk mengonfigurasi namespace khusus untuk kasus penggunaan tabrakan dengan pihak ke-3 atau komponen bersama lokal.

Sesuatu seperti "selector override".

Itu yang saya tanyakan

Terima kasih @robwormald atas wawasan terperinci Anda, tetapi satu hal dari pemula seperti saya (Kebanyakan, saya adalah pengembang backend). Saya belajar Angular 2 dan dengan TypeScript. Jadi konsep modul ES6 agak kabur bagi saya
Kami memiliki struktur aplikasi yang kompleks. Ini adalah aplikasi analitik, di mana jumlah komponen saya hampir 60.
Dan saya pikir itu terstruktur dengan baik di bawah RC4. Selain Login, kami tidak menggunakan jenis perutean apa pun, karena router membuat ulang seluruh komponen. Jadi Kami berencana sebagai aplikasi berbasis Tab. Ada dua tab utama (1.Analisis 2.Dashboard).
Tab Analytics akan memiliki beberapa tab yang masing-masing memiliki satu analisis di bawahnya. Dasbor juga akan memiliki
banyak tab tetapi setiap tab akan terdiri dari beberapa analisis yang disimpan di bawah
bagian analitik. Jadi bolak-balik dari banyak tab (di bawah dasbor dan analisis)
dan juga beralih antara Tab Dasbor dan Tab Analytics, kami merasa perutean tidak akan berfungsi
tujuan kita (koreksi saya jika saya mengatakan sesuatu yang bodoh).
Sekarang jenis RC5 NgModule melanggar aplikasi kita. Kami benar-benar tidak tahu bagaimana caranya
mendesain ulang aplikasi kita. Bisakah kita benar-benar menggunakan kompilasi AoT di aplikasi kita? Bukankah
seluruh hal AoT didasarkan pada perutean?

@shairez NgModules menyediakan spasi nama seperti ini. Biarkan saya mencoba untuk mengklarifikasi ini sedikit lebih jauh ...

Hal utama yang harus disadari di sini adalah bahwa komponen dikompilasi, kurang lebih, "di dalam" modul yang dideklarasikan - lihat https://plnkr.co/edit/9w10b1Y8Bjr5DDIxOwnC?p=preview untuk contoh.

Perhatikan bahwa ada dua pemilih yang saling bertentangan ( my-generic-selector ) - masing-masing modul fitur mengimpor salah satunya, dapat menggunakannya secara internal ke modul itu, tanpa mengotori ruang nama "global" apa pun.

Jadi digunakan seperti

<my-app>
  <!-- belongs to FeatureModuleOne -->
  <feature-one></feature-one>
  <!-- belongs to FeatureModuleTwo -->
  <feature-two></feature-two>
</my-app>

berkembang menjadi

<my-app>
  <!-- belongs to FeatureModuleOne -->
  <feature-one>
    <!-- the generic imported in FeatureModuleOne -->
     <my-generic-selector></my-generic-selector>
  </feature-one>
  <!-- belongs to FeatureModuleTwo -->
  <feature-two>
    <!-- the generic imported in FeatureModuleTwo -->
    <my-generic-selector></my-generic-selector>
  </feature-two>
</my-app>

tanpa konflik apa pun, karena ketika kompiler mengkompilasi fitur-satu dan fitur-dua, ia melakukannya _dalam konteks modul milik mereka_, yang menghindari polusi lingkup global.

@robwormald Tentu, itu luar biasa dan lebih baik daripada Angular 1 dalam pengertian itu.

Kasus penggunaan yang saya tulis mengacu pada pola penggunaan SharedModule global seperti yang disarankan dalam docs .

Jika saya mencoba mendeklarasikan GenericSelectorFeatureOne dan GenericSelectorFeatureTwo di dalam SharedModule , saya akan mendapatkan kesalahan bukan?

Atau jika SharedModule memiliki banyak komponen umum yang berguna dan saya ingin mengimpornya ke setiap modul fitur.

Jika modul fitur saya memiliki pemilih yang bertabrakan, atau pihak ke-3 memiliki pemilih yang bertabrakan dengan salah satu perpustakaan yang ada yang diekspor dalam SharedModule , itu akan mengeluarkan kesalahan bukan?

@shairez Saya pikir sebagian besar aplikasi akan berakhir dengan sejumlah "Modul Bersama", dan kemungkinan tabrakan rendah - modul murah, jadi tidak ada biaya besar untuk memiliki banyak.

Jika Anda memiliki ide tentang cara meningkatkan dokumen, maka PR akan disambut dengan senang hati.

Terima kasih itu adalah jawaban yang saya cari, saya akan mengujinya.

Saya belum memiliki ide yang lebih baik tentang bagaimana menyelesaikan ini dengan cara baru menulis modul, itu sebabnya saya menanyakannya di sini, tetapi begitu saya akan menguji beberapa solusi modul bersama, saya akan memiliki lebih banyak bahan untuk mendiskusikannya dengan @ wardbell dan menyerahkan PR.

Terima kasih atas bantuannya @robwormald !

Dari dokumen terbaru yang tersedia di https://angular.io , ada _banyak_ peringatan tentang anti-pola dan bug yang dapat dengan mudah muncul jika NgModule s disusun secara tidak benar. Sebagai contoh

Jangan tentukan penyedia tunggal seluruh aplikasi dalam modul bersama. Modul yang dimuat lambat yang mengimpor modul bersama itu akan membuat salinan layanannya sendiri.

Itu agak meresahkan. Jika Anda mengikuti pendekatan yang dicoba dan benar dari _pertama membuatnya bekerja, kemudian membuatnya cepat_, Anda mungkin perlu menyesuaikan modul mana yang dimuat dengan penuh semangat atau malas berdasarkan metrik empiris dan struktur yang muncul dari modul ini saat aplikasi atau pustaka Anda berkembang. Pada dasarnya, mengapa modul harus peduli jika dimuat dengan malas atau bersemangat?

Masalah lain yang tampaknya lebih serius muncul dari menyandingkan bagian berikut dari dokumen

Misalkan sebuah modul memerlukan HttpBackend khusus yang menambahkan header khusus untuk semua permintaan Http. Jika modul lain di tempat lain dalam aplikasi juga mengkustomisasi HttpBackend atau hanya mengimpor HttpModule, itu bisa menimpa penyedia HttpBackend modul ini, kehilangan header khusus. Server akan menolak permintaan http dari modul ini.
Hindari masalah ini dengan mengimpor HttpModule hanya di AppModule, modul root aplikasi.

Bisakah saya mengekspor kembali kelas dan modul?
Sangat!
Modul adalah cara yang bagus untuk mengumpulkan kelas secara selektif dari modul lain dan mengekspornya kembali dalam modul kenyamanan yang terkonsolidasi.
Sebuah modul dapat mengekspor kembali seluruh modul yang secara efektif mengekspor kembali semua kelas yang diekspor. BrowserModule Angular sendiri mengekspor beberapa modul seperti ini:
ekspor: [CommonModule, ApplicationModule]
Sebuah modul dapat mengekspor kombinasi dari deklarasinya sendiri, kelas impor yang dipilih, dan modul yang diimpor.

Jadi di satu sisi, dokumen mencegah pengguna mengekspor kembali modul tertentu, sementara pada saat yang sama menyatakan bahwa hal itu memberikan kemudahan yang besar.

Gagasan ekspor ulang NgModule analog dengan ekspor ulang Modul ES kecuali bahwa Anda memiliki kontrol yang lebih sedikit. JavaScript dicakup secara statis (ya saya tahu this tidak) dan itu adalah salah satu kekuatan terbesarnya, memungkinkan komposisi yang sangat fleksibel, dan penyembunyian informasi. JavaScript juga mendukung bayangan sehingga Anda selalu memiliki cara untuk mengganti cakupan.

Masalah terbesarnya, adalah bahwa contoh-contoh dalam pedoman semuanya berkisar pada cara mengimpor modul kerangka kerja @angular/*. Ini secara alami dapat dibagi dengan cara yang memungkinkan konflik dicegah secara intuitif. Ini karena mereka ada untuk menyediakan layanan tingkat infrastruktur yang umumnya tidak tumpang tindih. Modul yang ditentukan pengguna dapat melintasi banyak lapisan dan mungkin ingin meningkatkan atau mengubah berbagai perilaku. Misalnya, modul logging mungkin menginginkan akses ke Router dan Http, layanan sementara pada saat yang sama menyediakan beberapa komponen untuk menampilkan info kepada pengguna administratif dan menggunakan salah satu modul formulir untuk mendefinisikannya.

Dokumen tidak mengatakan apa-apa tentang apakah ekspor ulang bersifat transitif... Modul A mengekspor kembali CommonModule. Modul B mengekspor kembali Modul A. Modul C mengimpor Modul B. Apakah itu berarti bahwa Modul C sekarang dapat menggunakan arahan dari CommonModule?

@Martin-Wegner Mereka transitif seperti yang dijelaskan di sini https://angular.io/docs/ts/latest/cookbook/ngmodule-faq.html#! #q-ekspor ulang

@aluanhaddad dimana? Saya tidak dapat menemukan kata tentang re-ekspor transitif dengan lebih dari satu hop...

Membaca apa yang diambil @aluanhaddad dari dokumen angular, saya merasa harus mempertimbangkan kembali semua yang telah saya pelajari tentang Angular 2 dan mungkin bahkan jika tidak ada kerangka kerja yang menangani dependensi dengan cara yang lebih baik.

Seperti yang saya pahami. Jika saya memiliki Modul Aplikasi yang mengimpor HttpModule dan saya memiliki Modul Fitur dengan layanan, yang menggunakan Layanan Http, saya tidak boleh mengimpor HttpModule pada tingkat Modul Fitur tetapi pada tingkat Modul Aplikasi. Jadi bagaimana jika saya membuat Modul Fitur yang dibagikan di antara banyak Modul Aplikasi? Saya harus benar-benar menggunakan HttpModule yang diimpor di Modul Aplikasi. Saya tidak tahu, bahwa Modul Fitur saya bergantung pada HttpModule. Itu benar-benar jelek dan artinya, definisi NgModule itu tidak memiliki banyak fitur seperti misalnya PeerDependecies.
Oh Boy. Rasanya seperti sudut 2 pecah. Saya khawatir sudah waktunya untuk memulai kembali, meninggalkan sudut 2 dan mulai dengan sudut 3.

Sebenarnya ada begitu banyak arti dalam apa yang baru saja Anda katakan. Saya memulai ini
perjalanan angular2 sejak tahun lalu dan tidak punya alasan untuk merasa berdebar
terlepas dari semua perubahan besar yang telah kita lihat sejauh ini (dari alfa, beta,
dan RC). Itu bisa dimengerti pada fase-fase itu dan karena itu macet secara agama
dengan filosofi yang digunakan dalam mengubah saya keluar dari Backbonejs minimalis saya.
Seluruh ide ngModules ini bagi saya telah terbukti agak kontra
produktif. Dan sedih untuk menonton sepanjang waktu yang saya habiskan untuk menginjili
kebaikan yang kaya dari "Komponen" minimalis dan bebas mengasapi pergi ke
benar-benar sia-sia.
Pada 29 Agustus 2016 09:44, "Daniel Schuba" [email protected] menulis:

Membaca apa yang diambil oleh @aluanhaddad https://github.com/aluanhaddad
dokumen sudut Saya merasa harus mempertimbangkan kembali semua yang saya miliki
belajar tentang Angular 2 dan mungkin bahkan jika tidak ada kerangka kerja yang
menangani dependensi dengan cara yang lebih baik.

Seperti yang saya pahami. Jika saya memiliki Modul Aplikasi yang mengimpor HttpModule dan saya
memiliki Modul Fitur dengan layanan, yang menggunakan Layanan Http, saya seharusnya tidak
impor HttpModule pada level Modul Fitur tetapi pada level Modul Aplikasi. Terus
jika saya membuat Modul Fitur yang dibagikan di antara banyak Modul Aplikasi? saya mempunyai
untuk benar-benar di HttpModule diimpor di Modul Aplikasi. Saya tidak tahu,
bahwa Modul Fitur saya bergantung pada HttpModule. Itu benar-benar jelek dan
artinya, definisi NgModule tidak memiliki banyak fitur seperti misalnya
Ketergantungan Rekan.
Oh Boy. Rasanya seperti sudut 2 pecah. Aku takut sudah waktunya untuk
mulai dari awal, tinggalkan sudut 2 dan mulai dengan sudut 3.


Anda menerima ini karena Anda berlangganan utas ini.
Balas email ini secara langsung, lihat di GitHub
https://github.com/angular/angular/issues/10552#issuecomment -243066961,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/AF675h8_np9i5cHgL8mMOOu8vMMQmWKkks5qkpv8gaJpZM4Jee-o
.

Bisakah seseorang mengoreksi saya jika saya salah.

Saya sedang berpikir untuk mengatur aplikasi sebagai berikut.

aplikasi
|--Hukum/
|----Banyak Komponen.
|----LawNGModule.
|--Pengguna/
|----Banyak Komponen
|----UserNGModule
|--AppNGModule
|--SomeFirstLeveComponents

Katakanlah saya ingin bekerja dengan Angular Material. Sebelumnya saya agak benci bahwa saya memiliki terlalu banyak pelat ketel yang mengimpor setiap elemen di setiap komponen. Sekarang saya akan menambahkannya ke modul NG. Tetapi karena saya memutuskan untuk menggunakan satu modul ng per fitur, saya harus melakukan impor untuk setiap modul ng yang saya pertimbangkan. Bukan hanya akarnya saja. Apakah itu benar?

Atau mungkin ini adalah kasus di mana Anda membuat modul x untuk mengekspor kembali y(Material) modul lain, dan Anda mengimpornya ke modul yang Anda butuhkan?

@ReneVallecillo Anda benar. Anda harus mengimpornya di setiap modul fitur. Atau Anda menambahkannya bersama dengan modul lain ke dalam modul bersama (menyembunyikan ketergantungan), yang mengekspornya kembali dan kemudian menggunakan modul bersama ini. Dan jika Anda mengekspornya kembali ke modul lain, Anda bahkan mungkin memiliki impor duplikat tanpa mengetahui dan melihatnya segera.

@robwormald Menanggapi komentar Anda di atas :

Namun, dalam mode AoT, ini bekerja sedikit berbeda - pada waktu pembuatan, kami secara statis (yaitu, tanpa mengeksekusi kode Anda) mengekstrak metadata yang sama dari kode sumber dengan memindai dekorator.

Apakah ini berarti Anda mengekstrak modul secara statis dari kode sumber asli, dan karena itu, kami secara efektif tidak dapat membuat modul secara dinamis?

Untuk mempermudah migrasi, saya berpikir untuk membuat fungsi yang akan membuat modul secara dinamis; sesuatu seperti ini:

function createModule (entryComponent: Type, dependencies: Type[]) {
    @NgModule({
        imports: [CommonModule, FormsModule],
        declarations: [entryComponent, ...dependencies],
        exports: [entyComponent]
    })
    class FeatureComponent {}
    return FeatureComponent;
}

Jadi sementara ini (mungkin?) akan bekerja dengan kompilasi JIT, itu tidak akan bekerja dengan AoT karena AoT secara statis mem-parsing kode sumber, mencari dekorator?

Kompleksitas yang tidak perlu ini di era ES@next.... @aluanhaddad membuat beberapa poin yang sangat bagus.

Seperti yang terjadi, saya tidak mungkin melihat diri/tim saya maju dengan Angular 2 jika ini adalah arah yang diinginkan. Dan sepertinya memang begitu, karena ini telah "ditutup".

Saya mungkin harus melakukan seperti @DaSchTour dan meneliti kerangka kerja front-end lainnya. Sayang sekali, karena beberapa bulan yang lalu, NG2 cukup menyenangkan untuk dikerjakan dan pilihan saya yang jelas dari sampah.

@iyobo selain rasa sakit awal perubahan, _vast_ mayoritas (dan saya berbicara dengan _lot_ pengembang) umpan balik pada NgModules telah positif.

Dilihat secara terpisah di aplikasi hello world, Anda dapat memperdebatkan "kompleks" ("tidak perlu" secara faktual salah, sesuai penjelasan di atas), tetapi mereka benar-benar menjadi milik mereka sendiri dalam aplikasi nyata - mengatur fitur, perutean malas, dan Semua AoT dibuat lebih sederhana dengan NgModules. Mengingat pilihan hari ini, saya masih memilih untuk menambahkan NgModules ke dalam kerangka kerja.

Saya bersama @robwormald di sini, kesulitan awal migrasi dari RC4/5 ke NgModules dapat dikelola setelah melihat keuntungan tidak harus mengimpor setiap komponen/pipa ke halaman yang baru dibuat.
NgModules mulai bersinar setelah menjadi sedikit lebih kompleks dan memiliki banyak komponen bersama.

Jauh lebih mudah untuk mengimpor SharedModule dan menyelesaikannya.

Hai @robwormald , Gagasan bahwa seseorang tidak setuju dengan arah Ng2 saat ini sama sekali bukan pernyataan faktual bahwa mereka hanya bekerja pada aplikasi tingkat "halo dunia".

"Pembagian fitur" yang Anda bicarakan ini bukanlah hal baru. Ini adalah sesuatu yang selalu dirancang sesuai kebutuhan agar sesuai dengan setiap produk/solusi individu menggunakan komponen.
Yang mengatakan, masih benar-benar tidak ada kompartementalisasi yang lebih besar daripada komponen yang menyatakan apa yang dibutuhkannya dengan sendirinya.

Sekarang untuk lazy loading, menarik kembali dan melihat sesuatu dari sudut pandang mata burung, keuntungan utama dari lazy loading adalah untuk meningkatkan kecepatan loading aplikasi. Saya pikir sebagian besar dari kita memiliki saluran pipa yang membuat ini berhasil. Masukkan minifikasi, kompresi, dan beberapa titik masuk aplikasi ala webpack.

Tampaknya bagi saya bahwa NgModules adalah solusi untuk mencari masalah, daripada solusi untuk masalah yang sebenarnya. Tapi sekali lagi, saya tidak bisa mengklaim tahu segalanya...

Saya pikir waktu itu akan menunjukkan jika memperkenalkan NgModules adalah ide yang bagus. Saya mendapat kesan bahwa Angular 2 saat ini hanya dibuat untuk mencapai tujuan desain tertentu. Tidak ada yang memikirkan hal-hal seperti tim dengan tingkat keterampilan yang berbeda, kode yang semakin tua dan yang diturunkan dari generasi ke generasi pengembang. Di dunia yang ideal mungkin terlihat seperti ide yang bagus. Namun pada kenyataannya NgModules memperkenalkan banyak jebakan dan kebingungan yang akan menyebabkan banyak masalah dalam fase pelatihan dan pengenalan ke proyek baru. Ini tidak sesederhana dan seintuitif dengan deklarasi pada level komponen. Ketergantungan disembunyikan dalam modul dan hanya masalah waktu Anda harus mulai meneliti modul tempat Anda berada.

Setelah melakukan transisi dari aplikasi yang lebih besar ke NgModules baru-baru ini, saya pikir itu sebagian besar adalah hal yang baik (sekarang setelah saya selesai dengannya, itu masuk akal). Saya benar-benar berpikir bahwa masalah utamanya adalah mereka memerlukan struktur komponen yang berbeda, sesuatu yang mungkin tidak cocok dengan cara Anda menyusun aplikasi Anda sebelumnya (setidaknya itulah yang terjadi pada saya).

Namun, saya merasa mereka seharusnya tidak ada sebagai satu-satunya solusi. Jika Anda melihat bagaimana komponen sangat umum dibuat, maka Anda akan menyadari bahwa sangat sering, mereka terdiri dari subkomponen kecil yang sangat terspesialisasi. Untuk subkomponen ini, yang tidak memiliki tujuan di luar komponen container tersebut, mempertahankannya dalam modul dengan cakupan yang lebih tinggi benar-benar membosankan dan dapat dengan cepat menghasilkan masalah pelingkupan.

Saya akan sangat menghargai jika ada mekanisme _di tambahan_ untuk NgModules yang memungkinkan komponen untuk mendefinisikan komponen atau arahan lain sebagai dependensi cakupan lokal yang hanya berlaku dalam komponen yang tepat (seperti bagaimana daftar directives bekerja sebelum modul).

Saya suka saran @poke untuk memiliki alternatif bagi mereka yang lebih suka tidak menggunakan NgModules Penuh.

NgModules ditambahkan di RC5 untuk memecahkan masalah dengan mendapatkan kompilasi dan pemuatan lambat untuk bekerja - jadi bukan bagian dari rencana induk asli itulah sebabnya mereka tidak cocok untuk beberapa kasus penggunaan (terutama jika Anda membangun aplikasi berdasarkan desain asli "komponen adalah raja").

Tentu saja mereka memperbaiki atau mengaktifkan beberapa hal tetapi membawa komplikasi mereka sendiri juga - lebih banyak hal untuk dipelajari dan dirancang oleh orang-orang yang sangat menantang ketika semua praktik dan pendekatan terbaik belum berhasil. Adopsi awal dapat membawa banyak rasa sakit, saya belajar itu dari perjalanan ke RC4.

Saya lebih menyukai paket sentris komponen asli yang mungkin menjadi alasan saya menemukan Komponen Polimer/Web lebih cocok sekarang. Modul terasa seperti setengah langkah mundur ke Angular 1.

Pada awalnya saya menolak perubahan penghapusan pipa dan arahan ini, tetapi sekarang saya terbiasa dan tampaknya tidak seburuk yang saya pikirkan.

Adakah yang bisa menunjukkan kepada saya bagaimana NgModules bekerja di aplikasi yang sangat kompleks di mana banyak komponen membutuhkan banyak komponen lain di berbagai level? Semua tutorial, contoh, dan repo yang saya lihat hanya menunjukkan cara mudah di mana modul merangkum barangnya sendiri dan menerbitkan (mengekspor) beberapa di antaranya ke orang lain.

Dalam proyek nyata ada banyak dependensi lintas yang diperlukan biasanya dengan rantai hierarkis. Entah bagaimana salah untuk membuktikan konsep sesuatu dengan contoh yang ditunjuk persis untuk itu.

@ untuk semua penulis Angular2 : dapatkah Anda memberi tahu kami dengan jujur ​​apa bagian negatif dari NgModules? Saya tahu Anda dapat menulis buku tentang semua hal yang baik. Tidak apa-apa. Tapi saya selalu harus berurusan dengan hal-hal buruk yang tersembunyi yang tidak akan jelas jika Anda tidak membicarakannya.

Adakah yang bisa menunjukkan kepada saya bagaimana NgModules bekerja di aplikasi yang sangat kompleks di mana banyak komponen membutuhkan banyak komponen lain di berbagai level?

Salah satu cara untuk melakukannya adalah dengan membuat modul dependensi hanya untuk komponen tersebut: Anggap Anda memiliki tiga set komponen A , B , dan C yang berisi banyak komponen masing-masing dan setiap set memiliki orang-orang yang agak terkait. Jadi ketiga set ini akan bekerja dengan baik untuk tiga modul terpisah.

Sekarang, komponen di setiap set tersebut memerlukan beberapa komponen dari set D . Komponen-komponen dalam D hanya digunakan untuk komponen-komponen dalam tiga set tersebut. Karena mereka digunakan di semuanya, Anda tidak bisa hanya menambahkan komponen ke modul tersebut (karena komponen hanya dapat menjadi bagian dari satu modul). Pada titik ini, Anda dapat menggabungkan A , B , C , dan D ke dalam modul raksasa, jadi semua dependensi ada di sana. Tapi itu tentu saja sangat berantakan. Sebagai gantinya, Anda cukup membuat modul baru untuk D yang hanya berisi dependensi tersebut. Modul ini tidak melakukan apa pun selain menyediakan akses ke modul tersebutw. Sekarang Anda dapat mengimpor modul itu di masing-masing dari tiga modul lainnya, dan dapat menggunakan komponennya. Tetapi karena komponennya masih “private”, Anda tidak mengekspor ulang modul atau mengimpor modul D di beberapa modul lain.

Karena impor modul hanya memengaruhi modul itu sendiri, ini memungkinkan semacam pelingkupan tanpa mencemari modul lain. Tentu saja, Anda harus membuat lebih banyak modul, tetapi begitulah cara kerjanya.

Saya dapat membagikan pengaturan saya saat ini. Saya telah menggunakan 3 modul dalam aplikasi: CommonModule, AppModule dan TestModule.

  • CommonModule mengimpor & mengekspor barang yang paling umum seperti HttpModule, FormsModule, MdInputModule dll
  • AppModule mengimpor BrowserModule, CommonModule, app.routing, dan komponen individual
  • TestModule mengimpor & mengekspor BaseModule, tetapi menimpa beberapa penyedia, seperti XHRBackend dengan MockBackend

Saya telah memperkenalkan pengaturan ini untuk menyederhanakan TestBed.configureTestingModule,
sehingga saya harus mengimpor TestModule dan kemudian hanya satu komponen seperti:

TestBed.configureTestingModule({
  imports: [ TestModule ],
  declarations: [ MyFormComponent ]
});

Satu kelemahan tambahan yang menjadi sangat jelas ketika saya bermigrasi dari RC-4 ke rilis adalah bahwa NgModules memberlakukan hukuman berat untuk refactoring sederhana di mana komponen hanya perlu dipecah. Dengan NgModules, Anda harus mengubah modul yang memuatnya, yang mungkin beberapa tingkat di atas pohon komponen konseptual, atau mempromosikan komponen dengan membungkusnya dalam NgModule dan kemudian menghapusnya dari NgModule induknya. Komponen refactoring sangat penting.

Ini terkait langsung dengan poin @poke

Saya akan sangat menghargai jika ada mekanisme selain NgModules yang memungkinkan komponen untuk mendefinisikan komponen atau arahan lain sebagai dependensi cakupan lokal yang hanya berlaku dalam komponen yang tepat (seperti bagaimana daftar arahan bekerja sebelum modul).

Saya sangat tidak setuju. Arsitektur modular seperti yang diusulkan oleh Angular 2 lebih mudah untuk diukur, disesuaikan, dan difaktorkan ulang jika diperlukan. Tentu, dari RC4 ke RC5 ada sedikit penyesuaian, tetapi jika ada, bagi saya NgModules telah terbukti memungkinkan aplikasi yang jauh lebih fleksibel.

Angular memiliki pendapat dan tentu saja tidak cocok untuk semua, tetapi NgModules juga bukan titik kegagalan untuk merancang aplikasi yang cerdas, modern, dan berkinerja tinggi.

@emilio-martinez: Menurut pendapat saya, NgModule tidak akan pernah diperkenalkan, jika Angular 2 tidak begitu lambat dalam bootstrap, ketika melibatkan JiT. Semua 'perbaikan' lainnya seperti 'penskalaan, penyesuaian, dan pemfaktoran ulang' dapat diperdebatkan, seperti yang ditunjukkan dalam diskusi ini.

Sudah cukup lama sekarang dan banyak dari kita memiliki waktu untuk sepenuhnya menyerap NgModule ke dalam pekerjaan kita. Saya pikir sekarang jelas bahwa seperti yang telah dijelaskan oleh beberapa orang, setelah Anda melewati speedbump untuk pindah ke sistem modul baru, ini memungkinkan beberapa hal yang cukup hebat. Bagi siapa saja yang mengendarai utas ini yang mengalami kesulitan menyerap NgModule, saya sarankan untuk menggulir seluruhnya dan membaca semuanya dari @robwormald dan @wardbell khususnya.

Saya percaya kita semua akan menemukan satu tahun dari sekarang bahwa banyak aplikasi Angular 2+ membuat penggunaan modul yang meresap dan mulus, pemuatan lambat, dan AOT. Saya percaya akan sangat rutin bagi sebagian besar atau hampir semua aplikasi untuk menggunakan hal-hal ini untuk mengimplementasikan visi "aplikasi progresif" di mana bahkan aplikasi besar yang kompleks memiliki waktu muat awal yang hampir instan dan kemudian dengan malas memuat (atau secara optimis malas memuat) fungsionalitas yang mereka membutuhkan. Hasilnya sebenarnya sangat luar biasa licin, dan dicapai dengan biaya yang sangat rendah untuk pengembang aplikasi individu: NgModule pada dasarnya adalah biaya itu, dan ini adalah transisi yang menjengkelkan tetapi kemudian hanya sedikit pekerjaan berkelanjutan yang dapat digunakan.

@kylecordes Saya harap Anda benar dan saya pikir itulah sikap yang benar untuk dimiliki.

@iurii-kyrylenko itu sangat benar.

Saya memang memiliki masalah dengan kompilasi sudut JavaScript saya karena seharusnya TypeScript mengkompilasi JavaScript saya, tapi itu masalah terpisah.

@kylecordes Saya pikir ada banyak hal yang perlu dipertimbangkan daripada hanya transisi. Modul memperkenalkan banyak kerumitan dan banyak kemungkinan tambahan untuk menambahkan bug ke aplikasi sendiri. Masalah terbesar adalah kebingungan dependensi. Yang akan menyebabkan banyak masalah di tahun-tahun berikutnya dalam pengembangan dengan sudut 2.

@aluanhaddad Saya percaya Angular menggunakan pembungkus tsc untuk dikompilasi. Ini bagus karena Anda bahkan dapat mengimplementasikannya ke dalam alur kerja pelari tugas, misalnya.

@iurii-kyrylenko kecepatan bootstrap juga sulit ditentukan berdasarkan RC4. Banyak pekerjaan yang telah dilakukan sejak saat itu hingga rilis final adalah pembersihan dan pengoptimalan. Dalam pengalaman saya, JIT yang dikompilasi Angular berjalan lebih cepat daripada RC4.

@DaSchTour dapatkah Anda menguraikan bug yang Anda temukan saat bekerja dengan NgModule?

@emilio-martinez itu bukan bug di NgModule tetapi bug yang akan muncul karena impor hilang atau contoh layanan duplikat yang akan dihilangkan atau ditemukan pada tahap pengembangan sebelumnya. Ini tentang mengimpor barang-barang di tempat saya menggunakannya dan bukan di suatu tempat. Saya tidak melihat apakah itu diperlukan atau digunakan dan di tempat mana barang itu dibutuhkan dan digunakan.

Pikirkan saja TypeScript bekerja dengan cara ini. Saya memiliki file dasar untuk modul saya, sebut saja _index.ts_ tampilannya seperti ini.

import {foo} from bar;
import {StartComp} from start;

StartComp.boot();

Daripada kita memiliki file bernama start.ts yang terlihat seperti ini.

export class StartComp {
   public static boot() {
      foo()
   }
}

Itulah yang dilakukan Angular dengan NgModules. Dengan beberapa keajaiban saya telah mengimpor sesuatu ke dalam modul dan itu muncul di ujung lain dari aplikasi saya. Anda harus tahu bahwa foo diimpor dalam index.ts dan dengan menjalankan StartComp dari indeks, impor di sana dapat digunakan dalam komponen.

Ketergantungan disembunyikan dan perlu penyelidikan tambahan untuk menemukannya.

@emilio-martinez

Dalam pengalaman saya, JIT yang dikompilasi Angular berjalan lebih cepat daripada RC4.

Saya memiliki proyek dengan kompleksitas sedang, berdasarkan MEAN stack dan Angular 2 final. Dibutuhkan sekitar 10 detik untuk menyelesaikan bootstrap dalam mode JIT di perangkat Android saya. Saya menganggap ini sebagai penundaan yang signifikan. Saat ini saya tidak dapat menggunakan kompilasi AOT tanpa mengubah kode sumber saya (masalah dengan anggota pribadi, operator elvis ...).

Adakah yang punya info tentang kinerja AOT + beban malas untuk proyek kehidupan nyata?

Saya percaya Angular menggunakan pembungkus tsc untuk dikompilasi. Ini bagus karena Anda bahkan dapat mengimplementasikannya ke dalam alur kerja pelari tugas, misalnya.

@emilio-martinez inilah yang tidak saya inginkan. Saya ingin mengkompilasi kode saya menggunakan versi TypeScript apa pun yang saya inginkan, misalnya 2.1.0-dev yang memiliki tingkat emisi rendah untuk async/menunggu. Saya tidak ingin Angular bertanggung jawab mengkompilasi file TypeScript saya, ini tidak boleh didelegasikan ke kerangka kerja, ini adalah peran bahasa. Tanpa keluar dari topik, saya tidak akan menyentuh @Script dengan tiang setinggi sepuluh kaki, syukurlah sudah mati.
Dari segi alur kerja, saya menggunakan JSPM dan terkadang Webpack, bukan pelari tugas tradisional, dan saya membiarkan IDE saya menangani linter saya.

Masalah lain adalah bahwa saya telah menulis dekorator yang abstrak di atas dekorator sudut dan saya sekarang mengerti bahwa aot akan mengabaikannya. Mempertimbangkan betapa beratnya sudut dekorator, saya sangat kecewa mengetahui bahwa kerangka kerja tidak akan sepenuhnya mendukung dekorator, memperlakukannya, selama AOT, sebagai anotasi statis ketika mereka sebenarnya adalah konstruksi runtime dalam bahasa yang mendasarinya.

@aluanhaddad penting untuk dipahami bahwa ada dua langkah berbeda yang terjadi selama kompilasi AoT - yang pertama adalah menghasilkan _new_ kode TypeScript, yang kedua adalah mentranspilasikan kode itu ke ES5/6. ngc melakukan keduanya sebagai kenyamanan, tetapi tidak ada yang melekat dalam AoT yang mengharuskan itu. Di dalam google, kami melakukan keduanya, dan kasus itu adalah prioritas. Siapa pun dapat mengimplementasikan host kompiler untuk mendukung pembuatan kode di lingkungan apa pun yang mereka inginkan.

Kami tidak (belum) mendukung abstraksi di atas dekorator bawaan angular, tetapi jika Anda ingin menggunakan sesuatu seperti https://www.npmjs.com/package/core-decorators , itu tidak masalah.

@iurii-kyrylenko menyarankan Anda menonton hari pertama dari AngularConnect, di mana LucidCharts berbicara tentang pengalaman mereka dengan AoT. Lihat https://youtu.be/xQdV7q3e_2w?t=1411

IMHO - Tujuan # 1 semua orang harus mendapatkan kompilasi AoT sesegera mungkin. Performanya tidak terkalahkan.

@robwormald Saya belum melihat opsi apa yang tersedia saat menelepon ngc - jadi ini mungkin sudah dicakup. Saya pikir opsi-opsi itu dapat meredakan kekhawatiran seperti yang disuarakan di sini, jika mereka memperjelas bahwa NGC memenuhi tujuan pertama sebagai alasan utamanya untuk ada di tujuan kedua sebagai kenyamanan/pengoptimalan. Jika dokumentasi atau bantuan menunjukkan cara menjalankan tsc secara terpisah untuk mereka yang lebih suka melakukannya, apakah itu dapat meredakan kekhawatiran lebih lanjut?

@kylecordes saya tidak berpikir dokumentasi akan mencakup cara mengimplementasikan host kompiler Anda sendiri dalam waktu dekat. Ini adalah kasus penggunaan tingkat lanjut, dan dengan demikian akan membutuhkan beberapa pembelajaran mandiri untuk diterapkan. Kami menerapkan hal serupa untuk CLI di sini https://github.com/angular/angular-cli/tree/master/packages/webpack

@robwormald Ah, maksud saya bukan mengimplementasikan host kompiler Anda sendiri. Saya hanya bermaksud "proses pembuatan" dua baris - pertama memanggil ngc untuk memancarkan beberapa TypeScript yang dihasilkan, kemudian memanggil tsc sendiri untuk mengkompilasi semua TypeScript (sumber Anda ditambah sumber yang dihasilkan) ke JavaScript. Ini memberikan jaminan cepat bahwa kode TypeScript hanya sedang dikompilasi ke JS oleh compiler TypeScript yang tersedia.

@robwormald Terima kasih atas balasan Anda.
Mengenai NGC, yang ingin saya ketahui adalah apakah saya dapat mengontrol versi dan pengaturan kompiler TypeScript di pass TS -> TS . Bisakah saya meneruskan TypeScript ke NGC atau apakah saya harus menggunakan versi tertentu yang membungkus versi TypeScript tertentu? Seberapa berpasangan mereka?

Mengenai dekorator, apakah ada masalah pelacakan dukungan untuk dekorator yang ditentukan pengguna yang abstrak di atas dekorator Sudut? https://www.npmjs.com/package/core-decorators adalah set dekorator ortogonal, tetapi saya memiliki dekorator yang menerapkan pola dan konvensi di aplikasi Angular saya dengan membungkus dekorator Angular. Kasus penggunaan yang jelas untuk ini adalah untuk secara otomatis membuat dan menerapkan awalan nama komponen di seluruh paket, tetapi ada juga yang lain.

Karena NGC tidak mendukung ini, bagaimana cara mengetahui dekorator mana yang spesifik untuk Angular?
Apakah itu cocok dengan dekorator sudut dengan nama?
Saya harap tidak karena itu akan melanggar pelingkupan leksikal JavaScript.
Skenario sederhana
_awesome-component-decorators.ts_

import { Component } from '@angular/core';
import template from './awesome-component.html';
import style from './awesome-component.less';

export const awesomeComponet = <T extends new (...args) => any>(target: T) =>
  Component({template, styles: [style], selector: snakeCase(target.name) })(target);

_konsumen.ts_

import { awesomeComponet } 'app/shared/awesome-component-decorators';

<strong i="19">@awesomeComponent</strong> 
export class AnAwesomeComponent { }

<strong i="20">@awesomeComponent</strong> 
export class AnotherAwesomeComponent { }

@jpsfs Sudahkah Anda menemukan solusi untuk memuat Komponen secara dinamis tanpa menambahkan deklarasi komponen ke modul aplikasi root? .

Saya juga bagian dari proyek migrasi angular 1.X ke Angular 4 . Proyek ini memiliki sejumlah besar komponen yang digunakan kembali dalam aplikasi berbeda yang malas dimuat berdasarkan konteks aplikasi.

Sesuai pemahaman saya di Angular 4

Kita harus menambahkan dependensi komponen ke dalam deklarasi root @NgModule seperti di bawah ini.

impor {platformBrowserDynamic} dari "@angular/platform-browser-dynamic";
impor {Komponen, NgModule} dari "@angular/core";
...
...
@NgModule({
impor: [BrowserModule ], // impor Angular's BrowserModule
bootstrap: [BootStrapComp], // tunjukkan komponen bootstrap
deklarasi: [com1, comp2 , comp5 ...... Comp n ] // daftarkan komponen kita dengan modul
})
kelas ekspor AppModule {}

platformBrowserDynamic().bootstrapModule(AppModule);

Tetapi dalam kasus kami, kami tidak ingin me-root NgModule untuk mengetahui tentang dependensi komponen dalam waktu kompilasi. Sebaliknya kami ingin komponen dimuat secara dinamis dalam Run time .
Apakah Anda menemukan solusi bagus yang dapat mem-bootstrap aplikasi tanpa menambahkan semua komponen ke dalam deklarasi root NgModule (Dan kami juga tidak ingin memiliki satu NgModule untuk setiap komponen :))

@DaSchTour

Ingat saat titik masuk aplikasi Anda terlihat seperti ini?

Nah untuk itu sebagian dari kita menggunakan skrip build untuk secara otomatis membutuhkan modul ini dan menambahkannya ke modul aplikasi.

Saya mencari solusi yang serupa dan mudah di angular2.

@samudrak Anda tidak dapat malas memuat hanya komponen jika Anda ingin menggunakan dukungan Angular aot. Anda perlu mengatur modul malas untuk setiap komponen dan memuat modul dengan malas. Kami menggunakan pendekatan serupa dalam aplikasi kami...

Dengan dukungan impor dinamis di ECMAScript dan sekarang di TypeScript (dengan pemeriksaan tipe lengkap ortogonal untuk memuat), kasus penggunaan pemuatan malas cukup arbitrer. Tentu saja melihat ke belakang adalah 20/20 dan tidak ada cara untuk mengetahui itu akan terjadi.

Masalah ini telah dikunci secara otomatis karena tidak ada aktivitas.
Silakan ajukan masalah baru jika Anda mengalami masalah serupa atau terkait.

Baca lebih lanjut tentang kebijakan penguncian percakapan otomatis kami.

_Tindakan ini telah dilakukan secara otomatis oleh bot._

Apakah halaman ini membantu?
0 / 5 - 0 peringkat