Saya menggunakan AngularJS untuk membangun kontrol HTML yang berinteraksi dengan aplikasi Flex yang lama. Semua panggilan balik dari aplikasi Flex harus dilampirkan ke jendela DOM.
Misalnya (dalam AS3)
ExternalInterface.call("save", data);
Akan menelepon
window.save = function(data){
// want to update a service
// or dispatch an event here...
}
Dari dalam fungsi pengubahan ukuran JS Saya ingin mengirim acara yang dapat didengar oleh pengontrol. Tampaknya menciptakan layanan adalah cara yang harus dilakukan. Bisakah Anda memperbarui layanan dari luar AngularJS? Bisakah seorang pengontrol mendengarkan acara dari suatu layanan? Dalam satu percobaan (klik untuk biola) saya lakukan sepertinya saya dapat mengakses layanan tetapi memperbarui data layanan tidak tercermin dalam tampilan (dalam contoh <option>
harus ditambahkan ke <select>
).
Terima kasih!
var injector = angular.injector(['ng', 'MyApp']);
. Melakukan ini akan memberi Anda konteks yang sama sekali baru dan duplikatmyService
. Itu berarti Anda akan berakhir dengan dua contoh layanan dan model dan akan menambahkan data ke tempat yang salah. Anda sebaiknya menargetkan elemen di dalam aplikasi menggunakanangular.element('#ng-app').injector(['ng', 'MyApp'])
. Pada titik ini Anda dapat menggunakan $ apply untuk membungkus perubahan model.Jawaban:
Interop dari luar sudut ke sudut sama dengan debugging aplikasi sudut atau mengintegrasikan dengan perpustakaan pihak ketiga.
Untuk setiap elemen DOM Anda dapat melakukan ini:
angular.element(domElement).scope()
untuk mendapatkan cakupan elemen saat iniangular.element(domElement).injector()
untuk mendapatkan injektor aplikasi saat iniangular.element(domElement).controller()
untuk mendapatkanng-controller
contoh.Dari injektor Anda dapat memperoleh layanan apa pun dalam aplikasi sudut. Demikian pula dari ruang lingkup Anda dapat memanggil metode apa pun yang telah dipublikasikan untuk itu.
Perlu diingat bahwa setiap perubahan pada model sudut atau setiap pemanggilan metode pada ruang lingkup perlu dibungkus
$apply()
seperti ini:sumber
[ng-app]
root-node tampaknya mundur ketika saya sudah memiliki referensi ke Modul ...angular.element(document.getElementById(divName)).scope()
tidak dapat mengaktifkan ini: Saya menelepon , tetapi saya tidak dapat menjalankan fungsi apa pun darinya, itu hanya mengembalikan "tidak terdefinisi" di konsol.Misko memberikan jawaban yang benar (jelas), tetapi beberapa dari kita pemula mungkin perlu disederhanakan lebih lanjut.
Ketika datang untuk memanggil kode AngularJS dari dalam aplikasi legacy, anggap kode AngularJS sebagai "aplikasi mikro" yang ada dalam wadah yang dilindungi dalam aplikasi legacy Anda. Anda tidak dapat membuat panggilan secara langsung (untuk alasan yang sangat bagus), tetapi Anda dapat membuat panggilan jarak jauh melalui objek $ scope.
Untuk menggunakan objek $ scope, Anda perlu menggunakan $ scope. Untungnya ini sangat mudah dilakukan.
Anda dapat menggunakan id elemen HTML apa pun di dalam HTML "aplikasi mikro" AngularJS Anda untuk mendapatkan pegangan lingkup aplikasi $ AngularJS.
Sebagai contoh, katakanlah kita ingin memanggil beberapa fungsi di dalam pengontrol AngularJS kita seperti sayHi () dan sayBye (). Dalam AngularJS HTML (tampilan) kami memiliki div dengan id "MySuperAwesomeApp". Anda dapat menggunakan kode berikut, dikombinasikan dengan jQuery untuk mendapatkan pegangan $ lingkup:
Sekarang Anda dapat memanggil fungsi kode AngularJS Anda dengan cara menangani lingkup:
Agar lebih nyaman, Anda dapat menggunakan fungsi untuk mengambil pegangan lingkup kapan pun Anda ingin mengaksesnya:
Panggilan Anda akan terlihat seperti ini:
Anda dapat melihat contoh kerja di sini:
http://jsfiddle.net/peterdrinnan/2nPnB/16/
Saya juga menunjukkan ini dalam tayangan slide untuk grup Ottawa AngularJS (lewati saja 2 slide terakhir)
http://www.slideshare.net/peterdrinnan/angular-for-legacyapps
sumber
<input type="button" onclick="angular.element(this).scope().edit.delete();" value="delete">
Penjelasan terhebat dari konsep yang saya temukan ada di sini: https://groups.google.com/forum/#!msg/angular/kqFrwiysgpA/eB9mNbQzcHwJ
Untuk menghemat klik:
sumber
id
di elemen HTML atas kemudian melakukandocument.getElementById()
id itu. Ini memberi Anda akses ke lingkup pengontrol itu. metode / properti dll ... hanya memberikan poin bagus pada komentar goosemanjack.Lebih jauh ke jawaban lain. Jika Anda tidak ingin mengakses metode dalam pengontrol tetapi ingin mengakses layanan secara langsung, Anda dapat melakukan sesuatu seperti ini:
sumber
Berkat posting sebelumnya, saya dapat memperbarui model saya dengan acara asinkron.
Saya menyatakan model saya
Dan saya memperbarui model saya dari luar ruang lingkup saya
sumber
Cara yang lebih aman dan berkinerja terutama ketika men-debug data tidak aktif adalah dengan menggunakan variabel bersama untuk menahan fungsi panggilan balik. Pengontrol sudut Anda mengimplementasikan fungsi ini untuk mengembalikan internalnya ke kode eksternal.
Generalisasi sebagai arahan yang dapat digunakan kembali:
Saya membuat arahan 'exposeScope' yang bekerja dengan cara yang serupa tetapi penggunaannya lebih sederhana:
Ini menyimpan lingkup saat ini (yang diberikan ke fungsi tautan direktif) dalam objek 'lingkup' global yang merupakan pemegang untuk semua cakupan. Nilai yang diberikan ke atribut direktif digunakan sebagai nama properti lingkup di objek global ini.
Lihat demo di sini . Seperti yang saya tunjukkan dalam demo, Anda dapat memicu peristiwa jQuery ketika cakupan disimpan dan dihapus dari objek 'cakupan' global.
Perhatikan bahwa, saya belum menguji on ('scopeDestroyed') ketika elemen sebenarnya dihapus dari DOM. Jika tidak berhasil, memicu acara pada dokumen itu sendiri dan bukan elemen yang dapat membantu. (lihat skrip app.js) di dalam demo plunker.
sumber
Saya tahu ini adalah pertanyaan lama tetapi saya sedang mencari opsi untuk melakukan ini baru-baru ini, jadi saya pikir saya menaruh temuan saya di sini kalau-kalau itu berguna bagi siapa pun.
Dalam kebanyakan kasus, jika ada kebutuhan untuk kode warisan eksternal untuk berinteraksi dengan keadaan UI atau cara kerja aplikasi, layanan dapat berguna untuk menghilangkan perubahan-perubahan tersebut. Jika kode eksternal berinteraksi langsung dengan pengontrol sudut, komponen, atau arahan Anda, Anda sangat menyambungkan aplikasi Anda dengan kode lawas yang merupakan berita buruk.
Apa yang akhirnya saya gunakan dalam kasus saya, adalah kombinasi global yang dapat diakses browser (yaitu jendela) dan penanganan acara. Kode saya memiliki mesin pembuat formulir cerdas yang membutuhkan output JSON dari CMS untuk memulai formulir. Inilah yang telah saya lakukan:
Formulir Layanan Skema dibuat menggunakan injektor sudut seperti yang diharapkan:
Dan di controller saya: function () {'use strict';
Sejauh ini ini adalah pemrograman berorientasi layanan murni javascript dan javascript. Tetapi integrasi warisan datang ke sini:
Jelas setiap pendekatan memiliki kelebihan dan kekurangannya. Keuntungan dan penggunaan pendekatan ini tergantung pada UI Anda. Pendekatan yang disarankan sebelumnya tidak berfungsi dalam kasus saya karena skema bentuk dan kode lama saya tidak memiliki kontrol dan pengetahuan tentang cakupan sudut. Oleh karena itu mengonfigurasi aplikasi saya berdasarkan
angular.element('element-X').scope();
berpotensi dapat merusak aplikasi jika kita mengubah cakupannya. Tetapi jika aplikasi Anda memiliki pengetahuan tentang pelingkupan dan dapat mengandalkannya agar tidak sering berubah, apa yang disarankan sebelumnya adalah pendekatan yang layak.Semoga ini membantu. Umpan balik juga diterima.
sumber