Elemen Tidak Diketahui - Angular 2 Dengan Material Angular 2

Membenturkan kepalaku ke dinding pada saat ini. Saya mendapatkan kesalahan saat menjalankan aplikasi sudut 2 menggunakan SystemJS dan materi sudut, tidak tahu alasannya. Saya menggunakan proyek benih sudut: https://github.com/mgechev/angular-seed. Saya menambahkan materi melalui pedoman ini: https://github.com/mgechev/angular-seed/wiki/Integration-with-AngularMaterial2.

Kesalahan:

Unhandled Promise rejection: Template parse errors: 'md-toolbar' is not a known element:

rumah.component.html

<md-toolbar>Test</md-toolbar>

Konfigurasi SystemJS

this.NPM_DEPENDENCIES = [ ...this.NPM_DEPENDENCIES, {src: '@angular/material/core/theming/prebuilt/indigo-pink.css', inject: true} // {src: 'jquery/dist/jquery.min.js', inject: 'libs'}, // {src: 'lodash/lodash.min.js', inject: 'libs'}, ]; this.addPackageBundles({ name:'@angular/material', path:'node_modules/@angular/material/bundles/material.umd.js', packageMeta:{ main: 'index.js', defaultExtension: 'js' } });

Perhatikan bahwa tampaknya file sedang dimuat di browser saat memeriksa sumber dengan alat pengembang

Modul Aplikasi

...
import { MaterialModule } from '@angular/material';

@NgModule({
  imports: [BrowserModule, HttpModule, MaterialModule.forRoot(), AppRoutingModule, AboutModule, HomeModule, SharedModule.forRoot()],
  ...

package.json

  "dependencies": {
    "@angular/common": "~2.4.0",
    "@angular/compiler": "~2.4.0",
    "@angular/core": "~2.4.0",
    "@angular/forms": "~2.4.0",
    "@angular/http": "~2.4.0",
    "@angular/material": "^2.0.0-beta.2",
    "@angular/platform-browser": "~2.4.0",
    "@angular/platform-browser-dynamic": "~2.4.0",
    "@angular/router": "~3.4.1",
    "core-js": "^2.4.1",
    "intl": "^1.2.5",
    "rxjs": "~5.0.3",
    "systemjs": "0.19.41",
    "zone.js": "^0.7.4"
  }
  ...

Komponen Rumah

import { Component, OnInit } from '@angular/core';
import { NameListService } from '../shared/name-list/name-list.service';

/**
 * This class represents the lazy loaded HomeComponent.
 */
@Component({
  moduleId: module.id,
  selector: 'sd-home',
  templateUrl: 'home.component.html',
  styleUrls: ['home.component.css'],
})
export class HomeComponent implements OnInit {
...

T - Bagaimana cara memperbaiki masalah elemen yang tidak diketahui ini? Terima kasih!


person karns    schedule 25.02.2017    source sumber
comment
Periksa ke dalam package.json versi materi Anda.   -  person kind user    schedule 25.02.2017
comment
impor MaterialModule saja, bukan MaterialModule.forRoot() dan periksa.   -  person micronyks    schedule 25.02.2017
comment
@Kinduser - Menambahkan package.json untuk Anda.   -  person karns    schedule 25.02.2017
comment
@micronyks - Itu tidak memperbaiki atau mengubah kesalahan, terima kasih.   -  person karns    schedule 25.02.2017
comment
kesalahan apa yang kamu dapatkan?   -  person Aravind    schedule 25.02.2017
comment
apakah HomeComponent dideklarasikan di dalam HomeModule?   -  person snorkpete    schedule 06.03.2017


Jawaban (3)


Seperti yang tertulis di versi terakhir (2.0.0-beta.3 cesium-cephalopod (2017 -04-07)) Anda harus mengimpor MdToolbarModule ke modul yang memuat home.component.

Jika modulnya adalah home.module, muat saja MdToolbarModule di sana, seperti ini:

import { MdToolbarModule } from '@angular/material';

@NgModule({
    imports: [
        ...
        MdToolbarModule, // HERE YOU IMPORT THE TOOLBAR MODULE. IF YOU WANT ONLY THIS MODULE IN YOUR BUILD
        ...
],
...

Ini diperlukan karena AOT dan Lazy Load. Ini adalah satu-satunya cara Angular dapat menghapus kode yang tidak diperlukan. Jika Anda tidak memuat modul di setiap modul yang membutuhkan ini, kompiler tidak akan pernah tahu siapa yang menggunakan ini dan harus menambahkannya di semua komponen meskipun itu bukan komponen yang malas.

Alasan Anda tidak perlu memuat MaterialModule di komponen lain tetapi di app.module adalah karena app.module adalah titik masuk Anda dan selalu dimuat tidak peduli modul malas mana yang Anda muat. Kita dapat mengatakan bahwa app.module adalah bapak dari setiap modul, apakah mereka malas atau tidak.

Jadi, jika Anda memuat modul di app.module menggunakan forRoot() itu berarti Anda membuat instance global dari modul services dan semua komponen anak akan memiliki akses ke layanan tersebut. Inilah alasannya Anda tidak perlu memuat material.module di home.module lagi, karena MaterialModule digunakan untuk memuat layanan yang digunakan oleh Material untuk menghubungkan komponen material. Hanya itu yang dilakukan MaterialModule.

Setiap komponen material bersifat plug-and-play jika Anda sudah memuat MaterialModule di komponen bapak.

Untuk modul yang dimuat tanpa forRoot(), Anda tidak akan memiliki layanan tunggal sehingga Anda harus memuatnya di setiap komponen. Semua ini diperlukan untuk memungkinkan pohon bergetar lebih baik di mana Anda hanya memiliki apa yang Anda butuhkan dalam bangunan Anda.

person Bruno João    schedule 06.03.2017
comment
DOH! Tentu saja itu adalah sesuatu yang sangat jelas. Saya menghargai Anda yang memperhatikan hal ini. Itu memang karena proyek awal yang saya gunakan memiliki modul-modul terpisah... bisakah Anda menjelaskan mengapa mereka memutuskan untuk memasukkan setiap komponen ke dalam modulnya sendiri? - person karns; 07.03.2017
comment
Bagi saya, masing-masing modul adalah detail implementasi internal dari Angular Material. Pada satu titik, mereka menyarankan agar Anda mengimpor masing-masing modul yang Anda gunakan, namun dengan perpindahan ke dukungan pengguncangan pohon yang lebih baik, mereka sekarang menentukan MaterialModule sebagai modul yang seharusnya Anda impor. - person snorkpete; 07.03.2017
comment
@vinagreti, menurut saya komentar Anda tidak benar. Dia PERLU mengimpor MaterialModule di HomeModule, baik dia sudah mengimpornya di AppModule atau belum. Dan karena impor MaterialModule sudah ada, impor MdToolbarModule menjadi mubazir - person snorkpete; 07.03.2017
comment
@Snorkpete Saya telah memperbarui respons dengan lebih detail. - person Bruno João; 07.03.2017
comment
@vinagreti, Anda benar tentang layanannya - saat Anda mengimpor MaterialModule ke AppModule, layanannya dapat diakses dari injektor root, yang pada dasarnya berarti Anda dapat menggunakan layanan MaterialModule dari mana saja. Namun, hal yang sama TIDAK berlaku untuk deklarasi (komponen, arahan, pipa, yaitu hal-hal yang Anda gunakan dalam templat Anda). Untuk materialModule yang dapat dideklarasikan, Anda harus mengimpornya ke SETIAP modul yang Anda gunakan (atau sekali lagi, impor modul lain yang mengekspor MaterialModule) - person snorkpete; 07.03.2017
comment
B@Snorkpete Saya telah memperbarui respons dengan lebih detail. Tapi soal redundansi, pernyataan Anda salah. Ini semua tentang pemuatan yang lambat. MaterialModule adalah perekat untuk komponen-komponennya. Ini bukan sebuah komponen, juga bukan Modul untuk semua komponen. Itu hanyalah sekumpulan layanan yang digunakan oleh modul material. Anda harus memuat modul di setiap modul yang memerlukan ini. Ini adalah satu-satunya cara Angular dapat mengetahui apakah modul yang dimuat lambat memerlukan modul lain (mdToolbarModule dalam kasus ini) untuk memasukkannya ke dalam budle modul yang dimuat lambat. - person Bruno João; 07.03.2017
comment
@Snorkpete, saya tidak menemukan dokumen tentang ini, tetapi bagi saya, saya hanya memuat MaterialModule di app.module dan di anak-anak saya hanya memuat modul komponen sebagai mdInputModule mdIconModule. Dan AOT bekerja dengan sangat baik. Anda mungkin benar ketika mengatakan bahwa kami perlu memuat, tetapi kasus penggunaan tidak membuktikan maksud Anda. - person Bruno João; 07.03.2017
comment
@vinagreti, dalam contoh Anda yang sama, coba impor MaterialModule (bukan MdInputModule) di komponen anak dan Anda akan mendapatkan perilaku yang sama persis. Intinya adalah: Anda harus mengimpor Modul yang berisi komponen yang ingin Anda gunakan di setiap modul tempat Anda ingin menggunakannya. Apakah Anda mengimpornya dengan mengimpor MaterialModule atau dengan mengimpor modul individual (MdInputModule, MdToolbarModule dll) agak sewenang-wenang. Namun jika Anda memiliki modul fitur, tidak cukup hanya mengimpor MaterialModule di AppModule dan menyelesaikannya. Anda juga harus mengimpor ke modul fitur Anda - person snorkpete; 07.03.2017
comment
Mari kita melanjutkan diskusi ini dalam chat. - person Bruno João; 07.03.2017

@karns, Anda menyebutkan masalahnya ada di HomeComponent, dan saya perhatikan bahwa di daftar impor Anda, ada HomeModule.

Apakah HomeComponent milik HomeModule itu?

Jika ya, apakah Anda mengimpor MaterialModule ke HomeModule Anda?

Anda perlu mengimpor MaterialModule (atau modul yang mengekspor MaterialModule) ke setiap modul yang mungkin menggunakan komponen Angular Material dalam templatnya.

person snorkpete    schedule 06.03.2017
comment
Terima kasih atas jawabannya, Snork. Itu benar, namun saya akan menerima jawaban Vinagreti karena dia memiliki beberapa contoh kode. Terpilih. - person karns; 07.03.2017

Pilihan 1 :

  1. Pastikan Anda menggunakan perintah di bawah ini untuk menginstal materi ke aplikasi Anda

    npm install --save @angular/material
    
  2. Buka node_modules dan periksa apakah file-file ini ada

    node_modules/@angular/material/bundles/material.umd.js
    @angular/material/core/theming/prebuilt/indigo-pink.css
    
  3. Jika dua file di atas ada,

    • Delete the materials folder
    • Instal lagi
    • Sebelum instalasi, periksa apakah ada ketergantungan pada file package.json.
    • Periksa sekarang apakah file di atas ada sekarang.
  4. Di tab jaringan alat pengembang, periksa apakah Anda mengalami seperti di bawah ini

masukkan deskripsi gambar di sini

Pilihan 2 :

Jika solusi di atas tidak berhasil coba dengan ini

  1. Sertakan file di bawah ini dalam index.html masukkan deskripsi gambar di sini
  2. Di file config.js Anda hapus baris @angular/material dan gunakan referensi cdn di bawah ini

    '@angular/material': 'https://unpkg.com/@angular/material/bundles/material.umd.js',

DEMO LANGSUNG untuk menunjukkan bahwa referensi cdn berfungsi

Pembaruan 1: Plunker berfungsi dengan baik sekarang, Anda dapat melihatnya.

Penjelasan untuk opsi 2 adalah dengan menggunakan referensi cdn yang tidak peduli apakah Anda telah menginstal node_module atau tidak, dalam banyak kasus pasti akan berfungsi. Jika tautan cdn ini memperbaiki masalah Anda. perbarui saya Kami akan mencoba memperbaiki opsi 1 dalam kasus Anda.

person Aravind    schedule 25.02.2017
comment
Sayangnya opsi 1 tidak berhasil. Filenya ada di sana dan masih error. Bisakah Anda menguraikan opsi 2 butir #2? Saya berasumsi yang Anda maksud adalah konfigurasi SystemJS. Bisakah Anda memberikan konteks untuk perubahan kode? - person karns; 27.02.2017
comment
@karns akan melihatnya dan mengabari Anda suatu saat nanti - person Aravind; 28.02.2017
comment
Terima kasih atas bantuannya Aravind - sangat menghargai penyelidikan ini dan Anda memiliki beberapa saran berguna yang pada akhirnya mempersempit masalah, tetapi tidak menyelesaikannya. Namun, yang lain menjawab dengan benar. - person karns; 07.03.2017