Angular.js: angular.element.scope() mengembalikan tidak terdefinisi

Dibuat pada 9 Okt 2014  ·  29Komentar  ·  Sumber: angular/angular.js

angular.element.scope() tidak terdefinisi saat aplikasi dimuat di iframe dengan mengubah atribut iframe src.

Kode berikut harus mengembalikan referensi ke ruang lingkup tetapi mengembalikan tidak terdefinisi:

angular.element(document.body).scope()

Kode di atas dieksekusi di handler onclick setelah dokumen dimuat dan angular menyelesaikan bootstrap:

<script>
    document.addEventListener("click", function(){
        console.log(angular.element(document.body).scope());
    });
</script>

Masalah muncul dengan sendirinya ketika dokumen dimuat di iframe dengan memodifikasi atribut src-nya.
Diuji dengan 1.3.0-rc.5, tanpa jquery.

jqLite more info

Komentar yang paling membantu

Jika Anda ingin mengaktifkan informasi debug untuk sementara (misalnya untuk men-debug masalah pada aplikasi produksi langsung), Anda dapat menggunakan angular.reloadWithDebugInfo() seperti yang dijelaskan di sini .

Semua 29 komentar

Bisakah Anda memberikan plnkr reproduksi masalah ini?

Saya memiliki masalah yang sama di proyek saya sendiri, tetapi tidak dapat mereproduksinya menggunakan plnkr.

scope() mengembalikan undefined pada elemen apa pun.

Menggunakan JQLite atau JQuery 2.1.1 melakukan hal yang sama.

AngularJS 1.3.1.

Coba ini:

document.addEventListener('DOMContentLoaded', function () {
  angular.element(document.body).scope();
});

apakah Anda menonaktifkan info debug di proyek Anda @VictorQueiroz?

@caitp Anda telah menemukannya.

Mengaktifkan kembali info debug adalah solusi yang baik untuk masalah ini.

solusi yang bagus

:senyum: :senyum: :senyum:

Maaf guys untuk tidak bereaksi untuk sementara waktu. Masalahnya entah bagaimana terkait dengan jqCache, atau lebih khusus lagi dengan cara bagaimana expandoId dibuat. Di RC yang lebih lama, id dibuat seperti ini:
var expandoId = element[JQLite.expando];
Di yang lebih baru, id menggunakan properti hardcoded:
var expandoId = element.ng339;
Mengembalikan perubahan memecahkan masalah.
Sayangnya, saya tidak tahu banyak tentang hal itu, jadi jika seseorang dapat menjelaskan fungsinya, maka mungkin saya dapat menjelaskan masalah ini secara lebih rinci.

Oh wow terima kasih @caitp yang membuatku gila!
Harus ada catatan di dokumen di $compileProvider yang menjelaskan bahwa $compileProvider.debugInfoEnabled(false) akan membuat fungsi scope() kembali tidak terdefinisi, jika itu adalah perilaku yang diharapkan.

Sunting: salahku, itu sudah ada di doc

Panggil metode ini untuk mengaktifkan/menonaktifkan berbagai informasi runtime debug di kompiler seperti menambahkan informasi pengikatan dan referensi ke cakupan saat ini ke elemen DOM.

Apakah ada cara untuk mengatasi ini; memiliki debugInfoEnabled(false), tetapi masih dapat mengakses cakupan elemen?

Jika Anda ingin mengaktifkan informasi debug untuk sementara (misalnya untuk men-debug masalah pada aplikasi produksi langsung), Anda dapat menggunakan angular.reloadWithDebugInfo() seperti yang dijelaskan di sini .

Saya pikir @gkalpak mengklarifikasi banyak hal di sini!

Mengapa menutup? Menemukan solusi tidak berarti masalah telah diperbaiki, scope() harus mengembalikan cakupan terlampir terlepas dari mode debug.

Jika tidak memungkinkan, itu harus didokumentasikan dengan jelas di angular.element #scope() doc.

@Toilal Saya telah menutupnya karena sudah didokumentasikan seperti yang disebutkan dalam komentar sebelumnya di utas ini. Tetapi jika Anda percaya bahwa itu harus didokumentasikan di tempat lain juga, PR akan sangat dihargai!

Saya tidak bisa karena saya tidak yakin metode penyihir dari angular.element tidak akan berfungsi saat menonaktifkan debug. scope() pasti karena saya sudah mencobanya, tapi bagaimana dengan yang lain, seperti controller(), injector() ...

Setelah pengujian, itu hanya berdampak pada scope() dan isolateScope(). Saya akan mendokumentasikannya dan membuat PR.

Tetapi apakah ada cara untuk mengambil cakupan dari elemen DOM saat info debug dinonaktifkan?

@Toilal - tidak juga - info ruang lingkup dihapus karena mengeksposnya memiliki dampak kinerja - inilah mengapa disembunyikan di balik bendera debug.

Tetapi tidak akan sulit untuk menulis arahan yang dapat melakukan itu dan meletakkannya di elemen yang perlu Anda periksa

Terima kasih @pkozlowski-opensource. Saya telah menambahkan kalimat kecil pada scope() dan isolateScope() di dokumen, karena saya perlu beberapa waktu untuk mencari tahu mengapa metode tersebut tidak berfungsi di aplikasi saya.

@ocombe Itulah yang akan saya lakukan, karena saya sedang menulis komponen UI dan tidak dapat mengandalkan ruang lingkup/isolateScope karena pengembang akhir dapat menonaktifkan info debug (seperti yang disarankan).

setTimeout(fungsi() {
console.log(angular.element(document.body).scope());
}, 100);

qq 20160115164505

@ronnievdv

Apakah ada cara untuk mengatasi ini; memiliki debugInfoEnabled(false), tetapi masih dapat mengakses cakupan elemen?

Saya telah menggunakan metode snipet _(not recommended)_ berikut dalam fungsi link dari definisi direktif.

link: function(scope, element, attrs) {
  var isolatedScope = scope.$$childTail;
}

Apakah ada cara untuk memeriksa apakah debugInfo telah dinonaktifkan atau ada tanda untuk itu?

Dari dalam aplikasi, Anda dapat menggunakan $compileProvider.debugInfoEnabled() .
Jika Anda ingin men-debug instans langsung yang menonaktifkan info debug (misalnya penerapan produksi), Anda dapat memanggil angular.reloadWithDebugInfo() dari konsol dan itu akan memuat ulang aplikasi dengan info debug diaktifkan.

@gkalpak Saya hanya ingin memeriksa apakah info debug diaktifkan atau tidak. Agak seperti ini.

if(angular.isDebugInfoEnabled()) {
  // Do something
}

@hemkaran , masih belum jelas _di mana_ Anda ingin memeriksanya. Saya berasumsi dari dalam aplikasi Anda.
Jika memang demikian, Anda dapat menggunakan $compileProvider.debugInfoEnabled() .

@Toilal Apakah Anda menulis arahan seperti itu? Jika demikian, maukah Anda berbagi? Saya mengalami masalah ini sekarang. Saya berasumsi saya akan menemukan solusi, tetapi memiliki pendapat kedua tentang bagaimana menyelesaikannya benar-benar tidak ada salahnya.
cc @ocombe

Maaf saya tidak menggunakan Angular 1 lagi, dan saya tidak pernah menulis arahan seperti itu (karena saya hanya membutuhkan info ini dalam mode dev)

Saya melakukan hal berikut. Kami akan melihat apakah rekan tim saya akan membiarkannya melalui ulasan :)

function exposeScope() {
    return {
        restrict: 'A',
        link: function(scope, element) {
            element[0].APPNAME = {
                getScope: function() {
                    return scope;
                }
            };
        }
    };
}

return {
        restrict: 'A',
        scope: false,
        link: function(scope, elem) {
            elem.data('$scope', scope);
        }
    };

Anda juga dapat mengatur $isolateScope menjadi sama jika Anda membutuhkannya.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat