Angular: PENGECUALIAN: Ekspresi telah berubah setelah diperiksa.

Dibuat pada 18 Des 2015  ·  147Komentar  ·  Sumber: angular/angular

Komentar yang paling membantu

Ini bukan bug, ini adalah fitur mode dev yang berfungsi sebagaimana dimaksud. Memanggil enableProdMode( ) - lihat plunk yang diperbarui saat mem-bootstrap aplikasi mencegah pengecualian dilemparkan.

Yang mengatakan, itu dilemparkan untuk alasan yang baik: Singkatnya, setelah setiap putaran deteksi perubahan, mode dev segera melakukan putaran kedua untuk memverifikasi bahwa tidak ada pengikatan yang berubah sejak akhir yang pertama, karena ini akan menunjukkan bahwa perubahan sedang terjadi dengan mengubah deteksi itu sendiri.

Di plunk Anda, Anda memiliki ikatan [attr.spinner]=isLoading , dan isLoading berubah sebagai akibat dari panggilan Anda ke this.load() , yang terjadi ketika ngAfterViewInit diaktifkan, yang terjadi sebagai bagian dari giliran deteksi perubahan awal. Itu sendiri tidak bermasalah - masalahnya adalah bahwa this.load() mengubah pengikatan tetapi tidak memicu putaran baru deteksi perubahan, yang berarti bahwa pengikatan ini tidak akan diperbarui sampai beberapa putaran deteksi perubahan di masa mendatang.

Semua 147 komentar

Saya telah menghadapi masalah serupa, dan tampaknya disebabkan oleh bagaimana seorang anak diinisialisasi, dan bagaimana orang tua dapat memperbarui anak sebagai bagian dari proses inisialisasi. Saya memiliki sampel serupa dengan solusi buruk menggunakan zona: http://plnkr.co/edit/GI45u805pnFUtFeORnxn?p=preview , dengan solusi terlihat seperti berikut:

konstruktor(zona _ pribadi : NgZone) { }

ngAfterViewInit() : batal {
this._zone.overrideOnTurnDone(() => {
this.child.title = 'gelar dari orang tua';
});
}

Ini bukan bug, ini adalah fitur mode dev yang berfungsi sebagaimana dimaksud. Memanggil enableProdMode( ) - lihat plunk yang diperbarui saat mem-bootstrap aplikasi mencegah pengecualian dilemparkan.

Yang mengatakan, itu dilemparkan untuk alasan yang baik: Singkatnya, setelah setiap putaran deteksi perubahan, mode dev segera melakukan putaran kedua untuk memverifikasi bahwa tidak ada pengikatan yang berubah sejak akhir yang pertama, karena ini akan menunjukkan bahwa perubahan sedang terjadi dengan mengubah deteksi itu sendiri.

Di plunk Anda, Anda memiliki ikatan [attr.spinner]=isLoading , dan isLoading berubah sebagai akibat dari panggilan Anda ke this.load() , yang terjadi ketika ngAfterViewInit diaktifkan, yang terjadi sebagai bagian dari giliran deteksi perubahan awal. Itu sendiri tidak bermasalah - masalahnya adalah bahwa this.load() mengubah pengikatan tetapi tidak memicu putaran baru deteksi perubahan, yang berarti bahwa pengikatan ini tidak akan diperbarui sampai beberapa putaran deteksi perubahan di masa mendatang.

Saya perlu mengatur komponen saya di afterViewInit karena saya memiliki ChildView yang diinisialisasi di sini. Apa cara yang benar untuk membuat perubahan itu menjadi isLoading ? Bungkus panggilan ke this.load dengan setTimeout ?

Anda hanya perlu melakukan sesuatu, apa saja, yang memicu putaran deteksi perubahan lain selama metode itu - memancarkan peristiwa, apa pun. Membungkusnya dalam batas waktu (kilas balik antrian ke ng1 :-P) adalah salah satu cara yang berhasil, tetapi bagi saya terasa sangat berantakan di ng2.

Itu tidak terlihat ramah pengguna. Saya menganggap metode itu sebagai tempat saya dapat menyelesaikan inisialisasi komponen saya ketika anak-anaknya ditentukan dan sekarang ternyata memiliki beberapa aturan khusus. Saya pikir Anda harus memaksa putaran deteksi perubahan baru secara internal sehingga tersembunyi di dalam ng2 dari pengguna.

bisakah Anda memposting sampel yang lebih representatif dari apa yang ingin Anda capai di sini? jika itu pemintal gambar Anda, Anda akan lebih baik menggunakan penjilidan standar.

@AerisG222 juga untuk Anda. apakah ada alasan Anda tidak dapat menggunakan ikatan sederhana untuk mencapai ini? perilaku zona override biasanya tidak akan direkomendasikan.

@robwormald Ya, dalam hal ini saya bisa melakukan pengikatan properti. Kasus nyata yang saya miliki juga melibatkan properti lain yang sedikit lebih rumit - array objek khusus, tetapi itu juga pasti dapat diatur melalui pengikatan properti.

Saya kira jika tidak ada yang namanya @ViewChild , saya tidak akan terlalu peduli, karena ini akan menjadi satu-satunya cara yang masuk akal untuk menyampaikan informasi. Namun, saya sangat senang melihat @ViewChild sehingga saya dapat mengerjakannya untuk referensi komponen dalam kode. Ini menyederhanakan markup dan memungkinkan lebih banyak kontrol melalui kode, yang juga berharga dengan TypeScript karena ada lebih banyak dukungan perkakas (seperti intellisense dan pemeriksaan waktu kompilasi). Ini juga menyederhanakan komponen wadah karena tidak harus melacak variabel anggota yang dimaksudkan hanya untuk digunakan sebagai status untuk anak.

Poin kecil lainnya adalah ketika melihat aplikasi menggunakan sintaks pengikatan properti, Anda harus memeriksa template untuk melihat siapa yang pada akhirnya menggunakan data. Ini akan lebih jelas ketika ditransfer melalui kode.

Saya telah membersihkan kode untuk hanya menunjukkan apa yang penting untuk contoh. Idenya adalah untuk menampilkan pemintal hanya saat gambar sedang dimuat dan kemudian menghapus pemintal dan menampilkan gambar. Gambar dimuat hanya ketika elemen terlihat di layar.

inflate.ts

import {Component, Input, Renderer, ElementRef, AfterViewInit, ViewChild} from 'angular2/core';

@Component({
  selector: '[inflate]',
  templateUrl: './inflate.html',
  styleUrls: ['./inflate.css']
})
export class Inflate implements AfterViewInit {
  @Input('inflate') url: string;
  @ViewChild('holder') holder: ElementRef;
  isLoaded = false;
  isLoading = false;

  constructor(private renderer: Renderer) {}

  ngAfterViewInit() {
    setTimeout(_=> this.inflate()); // BUGFIX: https://github.com/angular/angular/issues/6005#issuecomment-165911194
  }

  inflate() {
    let bounds = <ClientRect>this.holder.nativeElement.getBoundingClientRect();
    if(bounds.bottom > 0 && bounds.top < window.innerHeight) {
      this.isLoading = true;
      let img = new Image();
      img.src = this.url;
      img.onload = _=> {
        this.isLoaded = true;
        this.isLoading = false;
        this.renderer.setElementStyle(this.holder,
          'background-image', 'url("' + this.url + '")');
      };
    }
  }
}

inflate.html

<image-holder #holder></image-holder>
<spinner *ngIf="isLoading"></spinner>

Saya perlu menjaga gambar tidak di Host karena sementara itu memudar dengan animasi saat memuat selesai, itu tidak akan mempengaruhi opacity latar belakang Host.

Saya punya masalah yang berpotensi terkait dengan arahan bersarang.
http://plnkr.co/edit/myX2Alx9jie2q0FDIME7?p=preview
Di sini saya mengikat ngStyle di progressBar.ts.
Saya mencatat objek gaya sebelum kembali untuk membuktikan bahwa mereka sama.
Saya juga mendapatkan ExpressionChangedAfterItHasBeenCheckedException .

@svi3c Anda sebenarnya mengembalikan objek _different_. Setiap panggilan fungsi akan mengembalikan instance objek baru yang "sama" dengan yang sebelumnya dalam hal kunci/nilai tetapi tidak dalam hal instance/referensi.

Ada beberapa cara untuk menghadapi situasi ini:

  • perbarui nilai dalam satu instance objek, alih-alih mengembalikan salinan baru
  • menggunakan strategi ChangeDetectionStrategy.OnPush sehingga fungsi Anda hanya dipanggil ketika salah satu input berubah, mis: http://plnkr.co/edit/NWyVoTtkiAzqWJphLMbi?p=preview

Anda mungkin ingin memeriksa https://github.com/ng-bootstrap/core/blob/master/src/progressbar/progressbar.ts sebagai contoh lain dari arahan progressbar untuk ng2 (menggunakan HTML/CSS bootstrap)

@pkozlowski-opensource Terima kasih banyak!
Saya hanya membaca https://angular.io/docs/ts/latest/guide/template-syntax.html#!#ngstyle dan saya belum menemukan strategi deteksi perubahan. Itu hebat! :)

@drew-moore:

Anda hanya perlu melakukan sesuatu, apa saja, yang memicu putaran deteksi perubahan lain selama metode itu - memancarkan peristiwa, apa pun.

Bisakah Anda memberi tahu apa cara _correct_ dan _simplest_ untuk memicu kembali deteksi perubahan dalam ngAfterViewInit - dengan asumsi semua yang diperlukan adalah properti yang akan diperbarui. ApplicationRef.tick() tidak berfungsi di sini karena menyebabkan pengecualian 'ApplicationRef.tick disebut secara rekursif'; memancarkan suatu peristiwa hanya untuk memicu deteksi perubahan terasa salah (dan tidak berhasil untuk saya), dan begitu juga setTimeout .

Berdasarkan komentar di sini tampaknya menjadi persyaratan yang cukup umum untuk memperbarui properti terikat di ngAfterViewInit (karena ketergantungan pada komponen anak), jadi Angular 2 tampaknya kehilangan cara sederhana untuk melakukan ini.

Jika memperbarui properti terikat di ngAfterViewInit adalah hal _salah_ yang harus dilakukan, apa alternatifnya?

Inilah yang cepat:

Tantangan:
Atur tinggi elemen dom (melalui rumus tertentu) berdasarkan lebar yang dirender.

Ekspektasi:
Saat elemen dirender, dapatkan lebarnya dan berdasarkan itu, hitung tingginya.

Realitas:
setWaktu habis?!

  ngAfterViewInit() {
    window.setTimeout(() =>
      this.elementHeight = (this.nativeElement.offsetWidth * this.randomImage.dim.h) / this.randomImage.dim.w
    )
  }

@Birowsky Plunker?

@zoechi Berikut ini contohnya: http://plnkr.co/edit/MML5uHEFQdL0k0TA5HtY

Anda dapat mengaktifkan setTimeout di app/app.component.ts#21 di kait siklus hidup ngAfterViewInit .

Saya juga mengalami hal serupa ketika mencoba menerapkan metode writeValue( newValue ) dari ngModel valueAccessor kustom. Ketika saya mencoba menerapkan newValue ke komponen, itu memberi tahu saya bahwa nilainya telah berubah (dengan cara yang buruk). Seperti yang telah Anda temukan, membungkusnya dengan setTimeout() "memperbaikinya"; tapi, tidak dengan cara yang baik.

Saya punya contoh lain . Ini sedikit lebih sederhana karena @HostBinding() diatur dan diinformasikan oleh QueryList .

Sama seperti masalah saya # 5950.

Beberapa rekomendasi di sini tentang cara melakukan ini dengan bersih.
http://stackoverflow.com/questions/34827334/triggering-angular2-change-detection-manually

Namun, saya masih membungkus setTimeout karena saya tidak bisa membuat mereka melakukan apa yang saya butuhkan. Sepertinya saya bisa ChangeDetectorRef.detectChanges() di akhir panggilan balik dan memicu CD.... Apakah saya melewatkan sesuatu? Mungkin itu akan membantu salah satu dari kalian.

Saya menggunakan ekstensi sumber media HTML5 untuk membuat konteks audio berdasarkan elemen video, jadi penggunaan @ViewChild diperlukan. Berdasarkan konteks audio saya mencoba menampilkan beberapa info, seperti jumlah saluran. Namun, saya juga mengalami masalah ini. Apa cara yang tepat untuk melewati ini?

@ElsewhereGames Sulit untuk mengatakan tanpa melihat beberapa kode yang sebenarnya. Bisakah Anda membuat Plunker?

@zoechi Saya tidak memiliki bug aktual untuk dilaporkan, hanya menyatakan bahwa tidak mengakses DOM secara langsung, meskipun diinginkan, itu tidak selalu sesuatu yang dapat dihindari (sebagai tanggapan atas komentar @robwormald ). Untuk API sebenarnya, lihat dokumen di createMediaElementSource .

Saya memposting kembali pada bulan Januari dengan masalah _ngModel_. Sekarang, saya kembali lagi dengan masalah _ViewChildren_. Namun, tidak seperti beberapa contoh lain ini, saya sebenarnya tidak mencoba melakukan apa pun dalam demo saya. Artinya, pengontrol saya tidak memiliki logika - semuanya adalah data meta dan ikatan tampilan. Karena itu, saya tidak yakin di mana saya memiliki ruang gerak untuk _mengacaukan segalanya_:

http://www.bennadel.com/blog/3040-i-have-a-fundamental- kesalahpahaman-of-change-detection-in-angular-2-beta-8.htm

Mengalami masalah serupa tetapi dapat menulis ulang kode untuk mengatasinya. Saya tertawa terbahak-bahak dengan postingan @bennadel jadi terima kasih. Bagikan beberapa perasaan dengan masalah sebelumnya yang saya miliki di mana deteksi perubahan pintar tidak cukup pintar, terlalu pintar, atau terlalu pintar untuk saya :-)

https://github.com/angular/angular/issues/6618

Sejauh ini selalu ada cara untuk mengatasinya, tetapi akan menyarankannya di sini lagi setidaknya mekanisme deteksi perubahan dapat menggunakan lebih banyak dokumentasi. @bennadel Masalah Anda mengingatkan saya pada masalah lain,

https://github.com/angular/angular/issues/5177

di mana untuk menyelesaikan ini disarankan agar kait siklus hidup tambahan ditambahkan OnBeforeBinding/OnBeforeRendering. Sepertinya solusi itu juga akan menyelesaikan masalah Anda.

@tandu ganti saja ngAfterViewInit menjadi ngOnInit

@tandu tidak masalah kapan pemintal Anda akan mulai (memuat anak, memuat gambar di anak - untuk pengguna semuanya memuat), hanya penting ketika Anda perlu mematikannya. Anda dapat mematikannya di "ngAfterViewInit", menggunakan setTimeout (saya setuju itu jelek), tetapi itu akan salah - komponen anak harus menjalankan acara ketika pemuatan gambar selesai, ke komponen induk. Memuat komponen anak dan memuat gambar adalah 2 peristiwa yang berbeda.

@e-oz https://github.com/angular/angular/issues/6005#issuecomment -165951692 Saya mengakses batas anak untuk mendeteksi apakah saya harus mulai memuat gambar.

@tandu dan Anda dapat memindahkan semua pemeriksaan ini ke kode komponen anak (akan sah di ngAfterViewInit dari komponen anak) dan mengirim acara ke induk, kapan harus mengubah isLoading.

@e-oz Saya mendefinisikan komponen sebagai #holder di html: <image-holder #holder></image-holder> . Jadi tidak ada file js untuk itu.

jadi buatlah, jika tidak, tidak perlu menggunakan ngAfterViewInit, jika View
tidak memiliki komponen nyata sebagai anak-anak - tidak ada yang akan dirender.

Pada Minggu, 13 Maret 2016 pukul 15:18 tandu [email protected] menulis:

@e-oz https://github.com/e-oz Saya mendefinisikan komponen sebagai #holder di html:

pemegang>

. Jadi tidak ada file js untuk itu.


Balas email ini secara langsung atau lihat di GitHub
https://github.com/angular/angular/issues/6005#issuecomment -195963389.

Saya juga dapat menggunakan element.getElementsByTagsName atau metode serupa dan tidak menggunakan ChildComponent. Pasti ada solusi. Saya baik-baik saja dengan perbaikan setTimeout . Masalahnya adalah nama metode menunjukkan bahwa itu dapat digunakan untuk mendefinisikan beberapa logika yang ingin komponen anak diinisialisasi dan dibatasi ke komponen tetapi metode tersebut tidak memberi tahu bahwa itu dijalankan di tengah siklus deteksi perubahan dan jadi kami punya waktu lama utas keluhan dari orang yang berbeda.

@tandu Saya sangat setuju dengan Anda dalam hal ini, ini adalah batasan yang sangat mengganggu.

Untuk apa nilainya, saya telah mengubah solusi asli saya menjadi berikut ini, yang mulai terasa seperti pendekatan yang masuk akal. Mungkin ini patut dicoba untuk situasi Anda:

    constructor(private _changeDetectionRef : ChangeDetectorRef) { }

    ngAfterViewInit() : void {
        // your code

        this._changeDetectionRef.detectChanges();
    }

Saya mendapatkan pengecualian yang sama saat menggunakan validasi formulir (input yang diperlukan). Terkait dengan masalah ini?

Plunker: http://plnkr.co/edit/Fp6XT5mC6ZCB14Z1gvTi?p=preview

@eivindr melihat sekilas dan saya belum pernah melihat ngFormControl pada input sebelumnya, tidak dapat melihat mengapa atau apa artinya karena harus menggunakan elemen formulir untuk mengikatnya ke grup kontrol dan input individu akan memiliki yang sesuai ngKontrol. Dalam hal apapun di plunker Anda, hapus

 [ngFormControl]="formModel.find('title')" 

dan itu memperbaiki kesalahan Anda.

Saya menolak untuk melepaskan masalah ini :) Kemarin, saya dapat menunjukkan bahwa masalah saya secara khusus terkait dengan pengikatan Host yang bergantung pada properti input :

http://www.bennadel.com/blog/3056-host-bindings-are-breaking-the-ngmodel-bridge-in-angular-2-beta-11.htm

Saya harus percaya bahwa ini adalah bug pada saat ini karena komponen memiliki dua hal yang bergantung pada Input - template tampilan dan binding Host - dan _hanya salah satunya_ yang menyebabkan pengecualian perubahan. Jika keduanya menyebabkan masalah, saya akan memikirkan hal lain; tapi, karena hanya satu dari mereka yang menyebabkan masalah, itu pasti bug, kan?

@eivindr Saya juga memiliki masalah yang sama ketika memulai dengan formulir kosong kemudian mengatur nilai kontrol formulir secara terprogram. Apakah Anda menemukan pekerjaan di sekitar?

@MarkPerryBV Tidak, saya masih mendapatkan "telah berubah setelah diperiksa" saat menggunakan diperlukan. Sama saat menggunakan validator pola. Tapi minLength dll berfungsi.

@ user414 Jika saya menghapus [ngFormControl]... tidak ada validasi "wajib" pada input.

@MarkPerryBV Saya telah menemukan solusi yang cocok untuk saya (untuk saat ini). Saya harus mengaktifkanProdMode(). Saya menggunakan ngIf pada input, jadi saya juga harus melakukan ChangeDetectorRef.detectChanges() setelah input diberikan (jika tidak, input tidak valid meskipun memiliki konten).

Menggunakan enableProdMode() tidak benar-benar memperbaiki apa pun - itu hanya menutupi gejala dengan menghentikannya melakukan pemeriksaan ulang dan memberi tahu Anda bahwa ada sesuatu yang mungkin salah.

Perbaikan AerisG222 tampaknya lebih baik daripada menggunakan setTimeout . Benarkah perilaku yang dimaksud adalah harus memicu deteksi perubahan secara manual setelah memanggil addControl() dengan validator?

Masalah yang sama di sini setelah memanggil addControl(). Saya pikir addControl() harus memanggil ChangeDetectionRef.detectChanges().

@CaptainCodeman saya tahu - itu adalah solusi sementara.

Ini tidak akan lagi gagal dalam mode dev ketika saya menggunakan ng2@beta17 , [email protected] , zone. [email protected]. Saya masih harus memanggil ChangeDetectionRef.detectChanges()

@eivindr dapatkah Anda memperbarui plnkr Anda ke perbaikan beta17?
Saya kehilangan akal untuk yang satu ini, saya menolak untuk tunduk pada enableProdMode() .

@AerisG222 Pendekatan Anda berhasil untuk saya!

Apakah menggunakan pendekatan yang diposting oleh @AerisG222 merupakan pendekatan yang baik untuk digunakan? Ya itu berhasil tetapi apakah ada hati nurani yang memicu secara manual changeDetectionRef.detectChanges() ?

Saya mengalami masalah yang sama ketika mencoba melakukan validasi formulir dinamis dan kemudian mengatur ulang formulir. di sini adalah plunk saya

Langkah-langkah untuk mereproduksi. Kirim formulir dengan Apakah Karyawan Diperiksa. Setelah formulir disegarkan, periksa kembali Apakah Karyawan.

Saya menggunakan changeDetectionRef.detectChanges() dalam fungsi kirim.

terima kasih untuk ini @AerisG222 :)

Saya tidak suka semua solusi setTimeout itu. Saya mengusulkan sebagai berikut:

http://plnkr.co/edit/9umnTGsdFWhbaOBeftuZ?p=preview

Menggunakan ChangeDetectorRef.detectChanges tidak selalu merupakan pendekatan yang baik. Contoh mengapa:

Komponen induk memanggil API publik komponen anak selama ngAfterViewInit . Panggilan ini mengubah ikatan anak. Memanggil detectChanges dari orang tua akan menyelesaikan masalah juga, tetapi itu berarti orang tua harus tahu kapan harus memanggil detectChanges setelah panggilan API anak mana. Anda akan melihat bahwa memanggil detectChanges dalam metode anak yang mengubah pengikatan dalam kasus ini tidak berfungsi ketika Anda ingin menggunakan ChangeDetectionStrategy.OnPush .

Saya mengalami kesalahan ini ketika menambahkan anak secara dinamis melalui ViewContainerRef.createComponent() dan kemudian memperbarui turunan anak. Saya menggunakan RC2 (dan mencoba untuk tidak menggunakan barang-barang yang disusutkan).

Awalnya semuanya berfungsi dengan baik (render pertama), tetapi kemudian saya menambahkan komponen yang akan memancarkan data baru. Peristiwa ini didengarkan oleh komponen induk, yang memperbarui larik datanya yang memicu deteksi perubahan dan populasi komponen turunan dinamis baru. Acara ini dipicu oleh pengiriman formulir. Jika saya menekan tombol kirim, semuanya baik-baik saja. Jika saya menekan enter untuk menghasilkan kiriman, itu akan menghasilkan kesalahan.

Saya akhirnya menambahkan ChangeDetectorRef.detectChanges() segera setelah pembuatan dan pembaruan komponen dinamis. Bukan masalah besar, tetapi tampaknya aneh bahwa meskipun saya baru saja menambahkan komponen baru ke tampilan, sistem tidak secara otomatis memicu deteksi perubahan untuk anak.

@aerisg222 Apakah saya perlu memanggil this._changeDetectionRef.detectChanges() Setelah setiap properti anak berubah dari induk?

Yah saya baru saja mengalami masalah ini. Saya memiliki dua komponen saudara menggunakan objek data yang sama. Kedua objek tersebut dianggap dapat memperbarui sumber data. Sumber lain benar-benar melihat perubahan pada objek tetapi memicu Ekspresi telah berubah setelah diperiksa. Nilai sebelumnya: 'benar'. Nilai saat ini: 'salah'

Ini terjadi pada saya setelah memutakhirkan dari RC1 ke RC4

Sama disini. Mulai mendapatkan ini lagi setelah memutakhirkan dari RC1 ke RC4.

Mungkin perubahan yang menyebabkan ini seharusnya dikomunikasikan sebagai perubahan yang melanggar dalam log perubahan ... kuz barang-barang saya rusak sekarang.

Kami harus menunggu final.
Saya berhenti menggunakan komponen anak karena memperbarui properti eksternal menyebalkan.
Saya pikir zona ada di sini untuk itu ...

Sama disini. Pemuatan komponen dinamis melalui ViewComponentRef tampaknya berperilaku berbeda di RC2 dan RC4 seperti di RC1

Berikut adalah dependensi kerja saya:
"ketergantungan": {
"@angular/common": "2.0.0-rc.1",
"@angular/compiler": "2.0.0-rc.1",
"@angular/core": "2.0.0-rc.1",
"@angular/http": "2.0.0-rc.1",
"@angular/platform-browser": "2.0.0-rc.1",
"@angular/platform-browser-dynamic": "2.0.0-rc.1",
"systemjs": "0.19.31",
"inti-js": "^2.4.0",
"reflect-metadata": "^0.1.3",
"rxjs": "5.0.0-beta.6",
"zone.js": "^0.6.12"
},
"devDependencies": {
"typescript": "^1.8.10",
"mengetik":"^1.0.4",
"bersamaan": "^2.2.0",
"lite-server": "^2.2.2"
}

Dan inilah dependensi yang menghasilkan kesalahan yang disebutkan:
"ketergantungan": {
"@angular/common": "2.0.0-rc.4",
"@angular/compiler": "2.0.0-rc.4",
"@angular/core": "2.0.0-rc.4",
"@angular/http": "2.0.0-rc.4",
"@angular/platform-browser": "2.0.0-rc.4",
"@angular/platform-browser-dynamic": "2.0.0-rc.4",
"systemjs": "0.19.31",
"inti-js": "^2.4.0",
"reflect-metadata": "^0.1.3",
"rxjs": "5.0.0-beta.6",
"zone.js": "^0.6.12"
},
"devDependencies": {
"typescript": "^1.8.10",
"mengetik":"^1.0.4",
"bersamaan": "^2.2.0",
"lite-server": "^2.2.2"
}

RC2 juga tidak berfungsi!

Hanya sebuah pertanyaan tetapi apakah ada cara untuk mendapatkan informasi lebih lanjut tentang kesalahan? Misalnya, akan menyenangkan untuk mengetahui apa "ekspresi" ketika kesalahan mengatakan "ekspresi berubah dari 'benar' menjadi 'salah'!.

Saya juga mengalami masalah yang sama persis setelah memutakhirkan dari RC1 ke RC4. Dan yang saya ketahui adalah karena fungsi ngOnInit di Component. Jika saya mengomentari fungsi ini, pesan kesalahan hilang dan semuanya berfungsi dengan baik. Ada pikiran?

Menutup masalah ini karena sudah tua dan tindakan telah diambil. Jika Anda masih mengalami masalah, pastikan untuk membuat masalah baru dan mengisi template masalah dengan semua detail yang diperlukan . Terima kasih

tetapi orang-orang mengatakan bahwa mereka masih mengalami masalah ini di rc baru...

Pada hari Rabu, 13 Jul 2016 pukul 00:52, Victor Berchet [email protected]
menulis:

Ditutup #6005 https://github.com/angular/angular/issues/6005.


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/angular/angular/issues/6005#event -720794445, atau bisukan
benang
https://github.com/notifications/unsubscribe/AAgIEFEVZmE0M53XxNpzAYg9hJT_E_viks5qVAyGgaJpZM4G4J_s
.

Ya, saya baru saja memutakhirkan ke RC4 dan tidak membuat satu perubahan pun pada komponen saya selain mengonfigurasi router baru dan mengalami masalah ini. Semuanya baik-baik saja di RC1, sepertinya ini masih ada.

Info lebih lanjut:

Ternyata karena async call di dalam ngOnInit , kesalahan ini terjadi. Jika saya mengomentari kode panggilan async atau memindahkan potongan kode itu ke konstruktor, semuanya berfungsi dengan baik.

@ammar91
Panggil ini setelah perubahan:
changeDetectionRef.detectChanges()

@zigzag95 Ya ini memang solusi tetapi rasanya sangat sulit untuk melakukan ini. Saya mengharapkan kerangka kerja seperti angular untuk menangani ini dengan lebih anggun daripada membuat kami secara manual memicu mekanisme deteksi perubahannya sendiri.

Dalam kasus saya, ini terjadi ketika saya berlangganan pemancar acara sudut di app.component.ts untuk menampilkan dan menyembunyikan bilah kemajuan. Itu semua baik dengan RC1 tapi istirahat di RC4.

Ini repronya, http://plnkr.co/edit/jEtfUrQdc4sJBySj5kWN?p=preview
Klik Tautan Pahlawan dan pilih salah satu pahlawan untuk diedit dan Anda akan melihat kesalahannya.
Silakan lihat perubahan di app.component.ts dan hero.service.ts

Hai @vicb , terima kasih atas pembaruannya. Bisakah Anda memberi tahu kami tindakan apa yang telah diambil? Apakah maksud Anda seperti ini akan diperbaiki di rilis berikutnya?

Solusi alternatif sederhana lain yang berhasil bagi saya adalah mengembalikan nilai sebagai nilai yang dapat diamati dan menunda nilai emisi sebesar 10 ms. Dalam kasus saya, pengecualian terjadi dengan nilai pemintal
<app-spinner *ngIf="spinner"></app-spinner>

  this.eventService.toggleSpinnerAnnounced$.subscribe(
      (show: boolean) => this.spinner = show
    );

ini berhasil untuk saya:

private spinner = new Subject<boolean>();
toggleSpinnerAnnounced$ = this.spinner.asObservable().delay(10); // This  delay() is important

announceSpinnerToggle(show: boolean) {
        this.spinner.next(show);
    }

Ini berhasil untuk Anda karena Anda menggunakan penundaan dan itu tidak terkait dengan yang dapat diamati.
Anda akan memiliki perilaku yang sama saat menggunakan stettimeout.

@Jarvens tolong berhenti memposting komentar ini di tempat yang tidak

Masalah GitHub adalah untuk laporan bug dan permintaan fitur.
Untuk pertanyaan dukungan, silakan gunakan saluran lain seperti yang tercantum di CONTRIBUTING - Punya Pertanyaan atau Masalah?

Komentar Anda tidak memberikan informasi yang cukup untuk mendiagnosis masalah Anda.

FYI: Saya mendapatkan kesalahan ini karena ekstensi chrome ng-inspector for AngularJS (alternatif ekstensi sudut 1 untuk batarang)

Ini gila! Setelah membaca seluruh utas, apa yang memperbaiki masalah dalam mode pengembangan adalah menonaktifkan ng-inspector untuk AngularJS seperti yang dikatakan @KarlGustav-unimicro.

Dengan itu ChangeDetectorRef.detectChanges() juga bekerja untuk saya tetapi terasa sangat kacau.

@pkozlowski-opensource,
saya masih tidak tahu mengapa indicatorStyle() akan dipanggil ketika salah satu input berubah,
bisa kasih penjelasan lebih lanjut?
Jika saya mengimplementasikan ngDoCheck di _progress-bar component_ tanpa menyetel ChangeDetectionStrategy.OnPush di komponen induk,
saya menemukan bahwa ngDoCheck dieksekusi dua kali,
saya tahu mengapa yang pertama akan dieksekusi,
tapi saya benar-benar bingung tentang ngDoCheck ...

http://plnkr.co/edit/myX2Alx9jie2q0FDIME7?p=preview

@LiTiang ,

saya masih tidak tahu mengapa indicatorStyle() akan dipanggil ketika salah satu input berubah,
bisa kasih penjelasan lebih lanjut?

Karena indicatorStyle() terikat ke [ngStyle] dalam tampilan, itu akan selalu dipanggil ketika detektor perubahan berjalan. Ini akan terjadi terlepas dari apakah input benar-benar berubah atau tidak.

saya menemukan bahwa eksekusi ngDoCheck dua kali,
saya tahu mengapa yang pertama akan dieksekusi,
tapi saya benar-benar bingung dengan ngDoCheck yang kedua ...

Ini kemungkinan besar karena, seperti yang disebutkan sebelumnya di utas ini, deteksi perubahan selalu berjalan dua kali dalam mode dev. Ini dilakukan untuk memverifikasi bahwa kami tidak memiliki kode yang mengubah binding selama deteksi perubahan, yang dapat menyebabkan bug yang sulit dalam produksi.

Variasi pada setTimeout()

PEMBARUAN: CPU menjadi 100% gila tanpa pendampingHeightPerbandingan terakhir: Pembaruan AFAIK akan rekursif!

UPDATE2: Contoh Plunker

Saya ingin ketinggian blok <ul> dinamis untuk mengontrol ketinggian <img> yang saya ikat ke "companionHeight".

Sangat jahat ... Tapi berikut ini berfungsi menggunakan Observable.

Berikut adalah elemen <ul> yang ketinggiannya sedang dipantau:

<ul class="title-list-ul" #listul (window:resize)="setCompanionHeight(listul)">

Berikut adalah elemen <img> yang dikontrol:

<img class="title-list-companion-img" [src]="getCompanionImageURL()" [height]="companionHeight"/>

Berikut adalah metode komponen yang berinteraksi:

import { Component, OnInit, AfterViewChecked, ElementRef } from '@angular/core';  // redacted
import { Observable } from 'rxjs';

@Component({
  selector: 'resume-title-list',
  templateUrl: './title-list.component.html',
  styleUrls: ['./title-list.component.scss']
})
export class TitleListComponent implements OnInit, AfterViewChecked {

  private error: Object;
  private companionHeight: number = 0;
  private companionHeightLast: number = 0;

   // Lots of irrelevant stuff like ngInit redacted for simplicity.

  constructor(private elementRef: ElementRef) { }  // redacted, mine is more complicated.

  setCompanionHeight(listElement: any) {
    let clientRect = listElement.getBoundingClientRect();
    if (clientRect) {
      this.companionHeight = clientRect["height"];
    }
  }

  // window::resize only happens when the window is resized: This is an initialization 
  // function that sets the initial size of the image... Without it the image height is 
  // initially zero and the image is not shown. 
  // The height was not correct in ngAfterViewInit, so I used ngAfterViewChecked instead.

  ngAfterViewChecked() {
    let ularray = this.elementRef.nativeElement.getElementsByClassName("title-list-ul");
    if (ularray && ularray.length > 0) {
        let h = ularray[0].getBoundingClientRect().height;
        if (h && h != this.companionHeightLast) {
          this.companionHeightLast = h;
          Observable
          .of(h)
          .delay(10)
          .subscribe(h => this.companionHeight = h,
                     error => this.error = error);
        }
    }
  }
}

Komentar tentang masalah tertutup mungkin tidak dibaca oleh anggota tim Angular.
Bagaimana dengan memposting pertanyaan di salah satu saluran ini CONTRIBUTING - Punya Pertanyaan atau Masalah? dengan Plunker untuk mereproduksi?

Saya memiliki masalah yang sama dengan:

<div *ngIf="isLoading">
   <app-some-viewchild></app-some-viewchild>
</div>

Gunakan [tersembunyi] sebagai gantinya *ngIf memecahkan masalah.

Saya bertemu masalah ini juga. Akhirnya, saya menemukan bahwa objek inisi default sama dengan objek ngModle.

mengatur changeDetection: ChangeDetectionStrategy.OnPush di dekorator @Component memperbaikinya untuk saya

@elvismercado terima kasih,

Saya memiliki komponen anak yang mengandalkan nilai yang diteruskan oleh templat induk, dengan templat anak melemparkan pengecualian ini ketika nilai induk berubah. Menambahkan saran Anda ke komponen anak menyebabkan deteksi perubahan tidak berjalan sampai nilai yang diubah didorong ke komponen anak, menghindari deteksi untuk berjalan sebelum waktunya, saya berasumsi?

Jika saya memiliki input yang memiliki fokus dan kemudian menghapusnya dari DOM (kondisi ngIf), kesalahan "Ekspresi telah berubah setelah diperiksa" terjadi (hanya jika input memiliki grup formulir yang terkait).
Inilah seorang plunker dengan masalah ini:
https://plnkr.co/edit/dooRvC1gY1WEcaNdshoP?p=preview
Terima kasih!

Jadi apa solusinya di sini?

Mengubah nilai input apa pun di ngOnInit akan memicu ini.

@coli
bungkus saja

setTimeout(()=>{
 ///your code here
}, 1);

Saya memiliki kombinasi komponen anak yang perlu dimuat sebelumnya ketika pengguna ingin mengedit entitas yang ada.
Saya telah berjuang dengan masalah ini selama berjam-jam sampai saya berhasil memperbaikinya menggunakan posting @drewlio di atas.

Suntikkan _changeDetectionRef:

    constructor(
        private _changeDetectionRef: ChangeDetectorRef) {
    }

Dan kemudian setelah melakukan perubahan, panggilan mendeteksi perubahan.
Ini berhasil untuk saya.

    setSizeFromCtrl() {
        console.log("setSizeFromCtrl");
        if (this.sizeFromList && this.tradeProfile && this.tradeProfile.SizeFrom && this.sizeFromCtrl) {
            this.sizeFromCtrl.select(String(this.tradeProfile.SizeFrom));
            this._changeDetectionRef.detectChanges();
            console.log("setSizeFromCtrl DONE");
        }
    }

    setCentreTypeCtrl() {
        console.log("setCentreTypeCtrl");
        if (this.centreTypeList && this.tradeProfile && this.tradeProfile.centreTypeList && this.centreTypeCtrl) {

            for (let i of this.tradeProfile.centreTypeList) {
                this.centreTypeCtrl.select(i.value);
            }
            this._changeDetectionRef.detectChanges();
            console.log("centreTypeCtrl DONE");
        }
    }


Perhatikan bahwa saya memiliki masalah yang sama tetapi penyebab yang berbeda (mirip?) Dan solusi yang berbeda.

  • Aplikasi Angular kami - https://github.com/GeoscienceAustralia/GNSS-Site-Manager , memiliki bentuk reaktif model yang bersarang dan dibangun di beberapa komponen di ngOnInit() . Beberapa formulir ini diciutkan dengan ngIf di template
  • Data juga dibaca dalam ngOnInit() dan diterapkan dengan theModelForm.patchValue(data)
  • Kesalahan ini muncul saat salah satu formulir yang diciutkan diperluas. Ini terkait dengan fakta bahwa DOM tidak dibuat karena formulir dibuat di ngOnInit() yang tidak diaktifkan hingga diperluas. Keluarkan patchValue() dan masalahnya hilang
  • Kami datang dengan dua solusi
  • Sebelum patchValue() menjalankan this._changeDetectionRef.detectChanges(); . Dan ubah ngIf menjadi [hidden] sehingga form dan DOM sepenuhnya dibangun. Sisi bawah dari ini adalah waktu dan biaya memori karena formulir lengkap dan DOM terkait dibuat (ini mungkin tidak menjadi masalah di banyak aplikasi tetapi bagi kami karena kami memiliki bentuk raksasa).
  • Solusi yang lebih baik adalah dengan menerapkan patchValue() (atau setValue() jika data dan bidangnya 1:1) dalam komponen dan dengan demikian hanya terjadi ketika formulir dibuat di ngOnInit() .

Saya belum melakukan perubahan ini (22/3/17).

Jadi saya tidak berpikir bahwa keputusan ini akan menyelamatkan semua orang.
Tetapi pada saya terjadinya kesalahan yang diberikan disertai dengan pembuatan elemen baru dari suatu kelas. Kemudian menambahkannya ke array, yang dihasilkan melalui *ngFor.
Saya memecahkan masalah ini dengan menambahkan konstruktor ke kelas saya, yang mengisi bidang yang diperlukan untuk menampilkan dalam template nilai default (nol, baris kosong)

export class Task {
    task_id: number;
....
    constructor() {
        this.task_name = '';
        this.task_desc = '';
        this.task_percent = 0;
  addNewTask():void{
    let newTask = new Task();
    this.tasksList.push(newTask);
  }

task_name & task_desc & task_percent yang saya tampilkan di template. Jika setidaknya salah satu bidang yang terdaftar tidak diinisialisasi dalam konstruktor, saya mendapatkan kesalahan serupa.

+1

Solusi AerisG222 berfungsi

constructor(private _changeDetectionRef : ChangeDetectorRef) { }

ngAfterViewInit() : void {
    // your code

    this._changeDetectionRef.detectChanges();
}

this._changeDetectionRef.detectChanges() berfungsi, tetapi itu akan menyebabkan masalah lain dalam kasus saya. Saya baru saja membungkus kode di dalam fungsi setTimeout() , itu menyelesaikannya.

@GuofuHuang melakukan itu adalah cara untuk menghindari masalah tidak memperbaikinya yang terkadang dapat menyebabkan siklus Deteksi Perubahan yang tak terbatas

@Toxicable Maaf, mungkin saya tidak menjelaskannya, saya tidak menggunakan this._changeDetectionRef.detectChanges(); Sebagai gantinya, saya membungkus kode sumber saya di dalam setTimeout().

@GuofuHuang jika apa pun yang Anda masukkan ke dalam setTimeout menyebabkan CD dan Anda menjalankannya pada kait siklus hidup maka mungkin Anda menyebabkan siklus CD tak terbatas. Solusinya adalah jangan membuat perubahan yang menyebabkan CD saat CD dijalankan

@Toxicable Bahkan saya mengaturnya 0?

@GuofuHuang jika pengaturan ke 0 menyebabkan CD maka ya

@Toxicable Saya baru saja menemukan tautan ini, http://stackoverflow.com/questions/779379/why-is-settimeoutfn-0-sometimes-useful , dikatakan bahwa setTimeout dari 0 adalah sesuatu seperti jeda/hasil di C, saya tidak' t tahu apakah itu akan menyebabkan CD apapun, tapi sekarang bekerja sempurna di tambang. Jika bukan solusi ini, apakah Anda memiliki solusi yang lebih baik untuk menyelesaikan masalah ini?

@GuofuHuang Saya tidak tahu apa yang dilakukan jeda/hasil di C tetapi di JS itu akan menempatkan panggilan balik ke akhir antrian acara. Solusi saya adalah seperti di atas: Solusinya adalah tidak melakukan perubahan yang menyebabkan CD saat CD dijalankan

settimeout adalah solusinya
Anda tidak perlu menentukan parameter ms dan saya akan menunggu satu centang

@zigzag95 @GuofuHuang lihat contoh ini mengapa setTimeout bukan solusi
https://plnkr.co/edit/dv8K9EvVQLG59Gxsl3oI?p=preview

@Toxicable Terima kasih, tetapi

@GuofuHuang Memang itu tidak akan terjadi dalam kasus Anda karena Anda melakukannya di ngAfterViewInit yang hanya dipanggil sekali. Maksud saya adalah mungkin menyebabkan loop tak terbatas dengan metode ini, oleh karena itu berbahaya untuk digunakan. Itulah yang plunkr tunjukkan.

@moutono Trik Anda telah membantu saya! Terima kasih banyak

Karena masalahnya adalah tentang memicu deteksi perubahan, menyelesaikan janji mungkin juga berhasil karena tambalan monyet ngZone juga menjanjikan. Yang ini berhasil untuk saya:

ngAfterViewInit() {
  Promise.resolve().then(() => your_code_here);
}

Ya setTimeout berfungsi, tetapi saya tidak suka perbaikan itu, dalam kasus saya itu disebabkan karena saya mengubah nilai pada EventEmitter
Solusinya adalah perubahan
private generalSubscriber: EventEmitter<any> = new EventEmitter<any>();
ke
private generalSubscriber: EventEmitter<any> = new EventEmitter<any>(true);

aneh kan?
Nah itu benar artinya, eventemitter tidak sinkron
https://angular.io/docs/ts/latest/api/core/index/EventEmitter-class.html

apakah ada solusi untuk ini? Kenapa ditutup?

Saya harus menghapus cache setiap saat

dalam kasus saya, saya mengganti rintisan gambar pada pemuatan gambar, harus meletakkannya di setTimeout

@intergleam @wasa4587 @caroso1222 @tandu @AerisG222 @drew-moore @robwormald @svi3c @pkozlowski-opensource @pcroc @zoechi @stefankoru @bennadel @bryanforbes @Necroskillz @drewlio @ElsewhereGames @zoechi @user414 @zoechi @user414

Ini kesalahan yang dihadapi saat berkembang. Di server produksi berfungsi dengan baik.

@smartHasmukh ini hanya kesalahan mode pengembangan, oleh karena itu tidak mengherankan.
Anda tetap harus memperbaikinya.

Jika kesalahan ini terjadi maka kemungkinan besar Anda memutus aliran data satu arah. Yang bisa berupa sesuatu seperti mengubah data satu komponen di saudara kandung, mengubah data induk di kait siklus hidup anak-anak, mungkin beberapa hal lagi.
Pengecualian ini dilemparkan bukan kesalahan, tetapi penolong bagi pengembang untuk memahami bahwa kontrak aliran data satu arah rusak dalam beberapa cara. Fakta bahwa ini berfungsi dalam produksi adalah kebetulan, Anda harus meninjau bagaimana Anda mengubah data Anda dalam komunikasi orang tua-anak, dan memperbaikinya dalam mode pengembangan.

@smartHasmukh Saya dulu juga merasa ini tidak nyaman. Misalnya, saya menghubungkan ke acara navigasi dan selanjutnya memancarkan acara ke komponen utama untuk menampilkan loader. Dan di setiap komponen saya kemudian menyembunyikan loader itu, setelah saya menerima data dari server (jadi, dalam langganan). Tidak apa-apa. Tetapi, dalam satu komponen, saya hanya mendapatkan beberapa data dari sumber "statis", tidak ada yang dapat diamati di sana, jadi saya hanya mencoba menggunakan ngOnInit untuk memberi tahu komponen utama untuk menyembunyikan loader. Lalu saya mendapatkan kesalahan, tentu saja.

Meskipun kasus saya seharusnya hal yang sederhana, itu bukan cara yang tepat untuk melakukannya. Saya harus mengambil keputusan untuk tidak menampilkan pemuat sejak awal, untuk komponen itu (yang bisa menjadi lebih rumit jika saya memiliki lebih banyak komponen seperti itu)... Atau, juga menangani penyembunyian pemuat dari layanan data saya , bukan pada tingkat komponen. Atau, perbaikan yang buruk, adalah dengan membungkus satu kasus tertentu dalam setTimeout(). Karena pendekatan awal tidak tepat.

TL/DR:
Saya yakin harus ada cara yang tepat untuk skenario Anda juga, selain perbaikan jelek _setTimeout()_ (yang telah saya _sadly_ pilih pada saat itu, tetapi sekali lagi, ini adalah skenario yang sangat sederhana dan saya tahu apa itu terjadi di sana - namun, saya mungkin harus mengubahnya di beberapa titik, dalam rilis mendatang).
Anda dapat mencoba StackOverflow untuk kasus spesifik Anda, berikan lebih banyak detail. Harus ada jalan.

Tentu Terima kasih @MrCroft @tytskyi dan saya akan melakukannya Pak @zoechi dan saya tahu Ini tidak mengejutkan. tapi aku hanya memberi tahu. tidak ada lagi

@tytskyi

Fakta bahwa ini bekerja dalam produksi adalah kebetulan, Anda harus meninjau

Tidak, dalam sebagian besar kasus, respons saya terhadap kesalahan ini adalah "ya, saya tahu, dan itu memang disengaja". Banyak komponen di aplikasi saya memuat sesuatu setelah init dan setelah menerima nilai baru dalam variabel terikat. Masalah ini hanya "keburukan yang diketahui" dari Angular dan tidak ada yang peduli.

@e-oz jika Anda memengaruhi status induk atau saudara kandung di salah satu kait siklus hidup, maka ini melanggar aliran data satu arah. Anda harus membuat perubahan seperti itu saat status aplikasi distabilkan, tetapi tidak di tengah deteksi perubahan. Itu sebabnya ada trik dengan microtask, setTimeout 0 dll.

@tytskyi tenang dengan "harus" Anda, saya membuat perubahan setelah stabilisasi - jelas jika dibaca dengan cermat - permintaan http untuk memuat data tambahan, jelas, akan memakan waktu lebih lama daripada stabilisasi awal. Anda tidak akan meyakinkan saya bahwa perilaku Angular ini benar, jangan coba-coba.

@e-oz bagaimana itu terkait dengan permintaan HTTP. Respons permintaan HTTP menyebabkan deteksi perubahan dan Anda tidak akan mendapatkan kesalahan "Ekspresi telah berubah ...".
Bisakah Anda memberikan informasi lebih lanjut?

@zoechi tidak ada alasan untuk membuang waktu, tidak ada yang akan mengubah apa pun, tugas ditutup.

@e-oz masalah ditutup setahun yang lalu dan tim Angular memiliki prioritas yang sangat berbeda saat itu (keluarkan rilis) dan masalah ini bukan pemblokir saat itu.
Jika Anda merasa memiliki kasus yang valid, Anda harus membuat masalah baru.

@zoechi Saya pikir Anda tidak akan memutuskan apa yang harus saya lakukan. Saya dapat membuat masalah baru, tetapi saya tidak harus melakukannya. Dengan segala hormat, saya tidak suka nada "seharusnya" itu.

@e-oz Saya mengerti, komentar Anda hanya untuk melampiaskan frustrasi Anda dan Anda tidak menarik untuk mendapatkan solusi. Tolong berhenti membuang waktu orang lain di sini dengan komentar tidak berguna Anda.

jika Anda memanggil http, berlangganan ke komponen Anda, tambahkan saja..
Promise.resolve().then(() => your_code_here);
atau
myObservable.delay(10).subscribe(...)

Salah satu dari dua solusi akan menyelesaikan masalah Anda

@vicb Berhenti menutup masalah yang tidak diperbaiki. Mengapa kau melakukan ini ?

Setidaknya menyarankan beberapa perbaikan yang benar, tetapi menutup ini tidak dapat diterima

@diegogarciaa ... dan apa sebenarnya yang tidak diperbaiki atau salah dari sudut pandang Anda? Percakapan ^^^ begitu panjang sehingga sulit untuk menemukan inti yang sebenarnya.

@mlc-mlapis dengan segala hormat, saya bukan guru Anda, jika Anda tidak dapat membaca atau memahami masalah, berhentilah mengganggu. Saya menghabiskan waktu lama untuk membaca semua konten, saya merekomendasikan hal yang sama.

Sikap tim sudut (tidak semua tim, tetapi yang di sini menutup masalah ini) tampaknya sangat giat: Tidak memblokir (gaji saya), tidak memperbaikinya dalam waktu dekat.

@diegogarciaa ... bagus sekali. Lanjutkan seperti di atas dan Anda akan diterima di mana-mana.

@mlc-mlapis Saya tidak ingin diterima di mana orang tidak bisa membaca dan mencoba omong kosong di tempat yang seharusnya tidak.

@diegogarciaa ... Saya hanya berpikir bahwa Anda secara pribadi memiliki masalah dan tampaknya itu tidak benar sekarang. Dan kenyataannya juga bahwa sebagian besar masalah dengan Expression has changed after it was checked ... bukanlah bug tetapi hanya kurang memahami cara kerja CD.

@mlc-mlapis ok...mari kita pahami

http://plnkr.co/edit/nm8OkrpZCIp4cvA6TbpO?p=preview

Dalam plunk ini saya dapat memahami variabel terikat dan diperiksa ketika ngAfterViewInit dipanggil, oleh karena itu ketika menerima nilai baru, dan tidak memicu putaran pemeriksaan baru, pengecualian dilemparkan

Tetapi misalnya, Jika saya memiliki referensi wadah tampilan ... dan saya menggunakan misalnya:

this.service.GetData().subscribe(
respon => this.component.instance.dataModel = respon
);

Pertimbangkan bahwa dataModel sedang digunakan sebagai {{ dataModel.Field }} di html saya

this.component adalah komponen dinamis yang dimuat pada peristiwa tertentu, bagaimana cara menghindari kesalahan? Manakah cara yang benar untuk meneruskan data ke komponen saya sebelum kait siklus hidup deteksi perubahan

@diegogarciaa ... ya, ini adalah contoh khas di mana operasi async dan sinkronisasi dicampur dan bertemu bersama dalam satu CD dan konfirmasinya dalam mode dev. Saya tidak akan mengulangi penjelasan dari postingan https://hackernoon.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4 , jadi mungkin coba baca dulu.

Dan lihat juga https://hackernoon.com/here-is-how-to-get-viewcontainerref-before-viewchild-query-is-evaluated-f649e51315fb.

Jadi artikel tersebut pada dasarnya mengatakan bahwa saya harus memanggil putaran deteksi perubahan secara manual...

Jujur saja saya sangat kesal dengan status saat ini ... bahkan hal-hal minimal di sudut sangat membosankan dan melelahkan ... Saya bahkan tidak bisa bernapas. Persetan denganmu

@diegogarciaa ... tidak, itu hanya solusi tambahan. Anda juga dapat menggunakan promise.then atau menggunakan setTimeout ... tetapi solusi yang disarankan dalam kasus ini mungkin adalah layanan bersama sehingga Anda tidak akan memperbarui secara langsung properti komponen dinamis melintasi siklus CD dan konfirmasi.

Atau buat saja instance dari komponen dinamis pada saat Anda akan memiliki datanya. Jadi langganan Anda akan meminta pembuatan instance komponen dinamis.

Tapi yang penting -> logika utama mengapa kesalahan terjadi -> karena perubahan searah harus selalu mengalir dari atas ke bawah melalui seluruh pohon dan setelah satu siklus CD ada konfirmasi status bahwa prinsip searah dihormati.

Ini "fuck you" bukan pribadi... hanya melampiaskan frustrasi saya.

Kami menggunakan skema direktif untuk menangani komponen kami. Kami membuat helper yang memuat komponen ke dalam referensi tampilan komponen, dan seperti yang kami pahami, data harus tersedia saat komponen sedang dimuat

protected loadPartialView(viewName: string, target: ViewContainerRef) : ComponentRef<any> {
        const factories = Array.from(this.resolver['_factories'].keys());
        const factoryClass = <Type<any>>factories.find((x: any) => x.name === viewName);
        const factory = this.resolver.resolveComponentFactory(factoryClass);
        return target.createComponent(factory);
}

Dalam contoh di atas: Saya ingin melakukan sesuatu seperti ini:

return target.createComponent(factory, dataSource);

Di mana sumber data saya akan tersedia pada waktu konstruktor

Seperti redux, yang menggunakan objek untuk menangani sumber data yang melewati komponen, kami berpikir untuk mengimplementasikan komponen injeksi yang menangani data untuk kami, sehingga kami bisa mendapatkannya sebelum lifecicle terhubung.

diegogarciaa

Saya tidak berpikir bahwa data harus tersedia sebelum ... komponen dinamis masih merupakan komponen dengan @Input() dan @Output() tetapi pertanyaannya adalah kapan Anda akan mengubah data.

... data harus tersedia saat komponen sedang dimuat ...

Saya kira Anda perlu menggunakan juga komponen dari modul yang dimuat lambat jadi saya menggunakan peta secara langsung dalam modul untuk memiliki kemungkinan mengakses komponen hanya dengan menggunakan nama string.

export default class LazyLoadedModule {
    cmps: Map<{}, {}> = new Map();
    constructor() {
        this.cmps.set('first-component', FirstComponent);
        ...
    }
}

Apa arti return target.createComponent(factory, dataSource); ? Karena API sebenarnya adalah createComponent(componentFactory, index, injector, projectableNodes, ngModule) .

Dan mungkin modul @angular/cdk yang baru akan menarik bagi Anda. Intro saja di sini: https://medium.com/@caroso1222/a -first-look-into-the-angular-cdk-67e68807ed9b.

Untuk apa nilainya dan jika itu dapat membantu siapa saja, alih-alih menggunakan setTimeout dan karena menggunakan ChangeDetectorRef.detectChanges() tidak berhasil untuk saya, saya akhirnya menggunakan NgZone.onStable dan menjalankan kode saya dengan berlangganan sekali di EventEmitter ...

constructor(
  private zone: NgZone,
) { }

ngAfterViewInit() {
  this.zone.onStable.first().subscribe(() => {
    // your code here
  });
}

Saya tidak sepenuhnya menyadari konsekuensi dari melakukan ini tetapi dapatkah ini lebih buruk daripada menggunakan setTimeout ? Jika ada yang punya komentar tentang hal itu akan sangat diterima!

@AerisG222 solusi bekerja untuk saya

constructor(private _changeDetectionRef : ChangeDetectorRef) { }

ngAfterViewChecked() : void {
    // your code
    this._changeDetectionRef.detectChanges();
}

ini adalah komponen html:

{{ lastData.note[i].date | tanggal : 'dd.MM.yyyy'}} | {{ lastData.note[i].date | tanggal: 'HH:mm' }}:#BFL15_200817 | {{ lastData.status.name }} oleh {{lastData.note[i].admin}}

Saya mendapatkan kesalahan jika data dalam array lebih dari satu, Adakah solusi?

Ini tentu saja merupakan masalah yang kompleks, tetapi untuk beberapa kasus (terutama ketika Anda memodifikasi properti pada ContentChild) ini dapat diselesaikan dengan memindahkan logika ke ngAfterContentInit() alih-alih ngAfterViewInit() atau ngOnInit()

Sungguh menakjubkan betapa hal-hal sederhana dapat menyebabkan begitu banyak kebingungan di sudut

Jangan khawatir, semua orang juga memperhatikannya
image

@jakeNiemiec pekerjaan lumpuh, troll, tidak ada yang mencari Angularjs lagi
https://trends.google.com/trends/explore?date=all&q=Angular%20tutorial ,React%20tutorial
image

Ya, saya berharap lebih banyak orang perlu mencari "tutorial sudut" di Google karena putus asa, oleh karena itu komentar awal tentang "kebingungan".

Tapi jangan khawatir, kami dapat memeriksa npm untuk statistik penggunaan yang tepat: http://www.npmtrends.com/react-vs-@angular/cli -vs-vue-vs-@angular/core
image
image

Bandingkan saja jumlah masalah. Saya benar-benar ingin melihat sudut menjadi lebih baik, tetapi saya menduga bahwa Vue.js akan meneruskannya di masa depan yang jauh. Setelah memprogram di ketiganya, saya sangat merekomendasikan Vue ke angular devs. Ini seperti sudut tanpa boilerplate.

ok jawaban diterima, saya baik-baik saja dengan statistik itu.
Saya membayangkan ada lebih banyak orang yang menggunakan PHP di India daripada Java di seluruh dunia. Seseorang akan menjadi idiot untuk menggunakan PHP untuk aplikasi perusahaan skala besar, jadi Anda harus menggunakan otak Anda sendiri kadang-kadang, hidup akan lebih baik

@jakeNiemiec ... 50% dari masalah yang dibuat salah ditempatkan di sana ... mereka adalah masalah dukungan / pengetahuan sebenarnya dan seharusnya tidak ada sama sekali. Yang menyenangkan adalah sebagian besar topik yang diperlukan didokumentasikan dengan sangat baik di dokumen resmi + jawabannya didasarkan pada pengetahuan JavaScript. Tapi Anda tahu, orang tidak membaca dokumennya cukup dalam.

@HostBinding dapat menjadi sumber yang membingungkan dari kesalahan ini.

Pertimbangkan pengikatan sederhana pada komponen, seperti @HostBinding('style.background') .

Properti itu diperiksa oleh deteksi perubahan komponen * induk * seolah-olah itu miliknya. Dari sudut pandang kami, kami ingin menganggapnya sebagai komponen anak yang 'memiliki' properti itu.

Jadi sepertinya harus ada cara bagi komponen untuk mengecualikan properti untuk diperiksa dalam kasus ini? Atau lebih rumit dari itu?

Saya harus menjalankan komponen induk saya detectChanges (atau menambahkan div tambahan pada anak) untuk menghindari kesalahan jika komponen anak hanya mengubah warna latar belakangnya sendiri (dan tidak pernah melakukannya di tempat lain) .

Deskripsi lebih lengkap: https://stackoverflow.com/questions/43375532/expressionchangedafterithasbeencheckederror-explained/51662105#51662105

Anda hanya perlu melakukan sesuatu, apa saja, yang memicu putaran deteksi perubahan lain selama metode itu - memancarkan peristiwa, apa pun. Membungkusnya dalam batas waktu (kilas balik antrian ke ng1 :-P) adalah salah satu cara yang berhasil, tetapi bagi saya terasa sangat berantakan di ng2.

Di sudut 4, itu berfungsi 4 saya <3

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