Saya ingin menyuntikkan layanan ke app.config, sehingga data dapat diambil sebelum controller dipanggil. Saya mencobanya seperti ini:
Layanan:
app.service('dbService', function() {
return {
getData: function($q, $http) {
var defer = $q.defer();
$http.get('db.php/score/getData').success(function(data) {
defer.resolve(data);
});
return defer.promise;
}
};
});
Konfigurasi:
app.config(function ($routeProvider, dbService) {
$routeProvider
.when('/',
{
templateUrl: "partials/editor.html",
controller: "AppCtrl",
resolve: {
data: dbService.getData(),
}
})
});
Tapi saya mendapatkan kesalahan ini:
Kesalahan: Penyedia tidak dikenal: dbService dari EditorApp
Bagaimana cara memperbaiki pengaturan dan menyuntikkan layanan ini?
Jawaban:
Alex memberikan alasan yang tepat untuk tidak dapat melakukan apa yang Anda coba lakukan, jadi +1. Tetapi Anda menghadapi masalah ini karena Anda tidak cukup menggunakan resolusi bagaimana mereka dirancang.
resolve
mengambil string layanan atau fungsi mengembalikan nilai yang akan disuntikkan. Karena Anda melakukan yang terakhir, Anda harus memberikan fungsi yang sebenarnya:Ketika kerangka kerja diselesaikan
data
, itu akan menyuntikkandbService
ke dalam fungsi sehingga Anda dapat dengan bebas menggunakannya. Anda tidak perlu menyuntikkan keconfig
blok sama sekali untuk mencapai ini.Selamat makan!
sumber
.service
, jadi pindah$q
dan ke$http
sana.pageData: 'myData'
, tetapi kemudian Anda harus meneleponpageData.overview
dari pengontrol Anda. Metode string mungkin hanya berguna jika pabrik layanan mengembalikan janji alih-alih API. Jadi cara Anda saat ini melakukannya mungkin adalah cara terbaik.Siapkan layanan Anda sebagai Penyedia AngularJS khusus
Terlepas dari apa yang dikatakan jawaban yang Diterima, Anda sebenarnya BISA melakukan apa yang ingin Anda lakukan, tetapi Anda perlu mengaturnya sebagai penyedia yang dapat dikonfigurasi, sehingga tersedia sebagai layanan selama fase konfigurasi .. Pertama, ubah Anda
Service
ke penyedia seperti yang ditunjukkan di bawah ini. Perbedaan utama di sini adalah setelah menetapkan nilaidefer
, Anda menyeteldefer.promise
properti ke objek janji yang dikembalikan oleh$http.get
:Layanan Penyedia: (penyedia: resep layanan)
Sekarang, Anda memiliki Penyedia kustom yang dapat dikonfigurasi, Anda hanya perlu menyuntikkannya. Perbedaan utama di sini adalah "Penyedia injeksi Anda" yang hilang.
konfigurasi:
gunakan data terselesaikan di
appCtrl
Alternatif yang Mungkin
Alternatif berikut adalah pendekatan yang serupa, tetapi memungkinkan definisi terjadi di dalam
.config
, merangkum layanan ke dalam modul spesifik dalam konteks aplikasi Anda. Pilih metode yang tepat untuk Anda. Lihat juga di bawah untuk catatan tentang alternatif ke-3 dan tautan bermanfaat untuk membantu Anda memahami semua hal iniBeberapa Sumberdaya yang bermanfaat
$http
spesifik dalam konteks permintaan inifactory
/service
/provider
di clevertech.biz .Penyedia memberi Anda sedikit lebih banyak konfigurasi atas
.service
metode, yang membuatnya lebih baik sebagai penyedia tingkat aplikasi, tetapi Anda juga bisa merangkum ini dalam objek konfigurasi itu sendiri dengan menyuntikkan$provide
ke konfigurasi seperti:sumber
$get
panggilan. Alih-alih, Anda ingin menambahkan metode pada instance penyedia dan kembali sajathis
ketika Anda menelepon$get
. Bahkan dalam contoh Anda, Anda hanya bisa menggunakan layanan ... Di penyedia Anda juga tidak bisa menyuntikkan layanan seperti$http
. Dan ini//return the factory as a provider, that is available during the configuration phase
adalah informasi yang menyesatkan / salahJawaban singkat: Anda tidak bisa. AngularJS tidak akan mengizinkan Anda untuk menyuntikkan layanan ke dalam konfigurasi karena tidak dapat memastikan mereka telah dimuat dengan benar.
Lihat pertanyaan dan jawaban ini: AngularJS ketergantungan injeksi nilai di dalam module.config
sumber
Saya tidak berpikir Anda seharusnya bisa melakukan ini, tetapi saya telah berhasil menyuntikkan layanan ke
config
blok. (AngularJS v1.0.7)sumber
.config
Anda telah menulis cacheBuster (yang tidak didefinisikan di mana pun dalam jawaban) dan dogmaCacheBusterProvider (yang tidak digunakan lebih lanjut). Apakah Anda akan menjelaskan hal ini?cacheBuster
didefinisikan, sebagai parameter dari fungsi konfigurasi. Sehubungan dengandogmaCacheBusterProvider
itu, sesuatu yang pintar yang dilakukan Angular dengan konvensi penamaan, yang sudah lama saya lupakan. Ini mungkin membuat Anda lebih dekat, stackoverflow.com/a/20881705/110010 ..provider()
resep. bagaimana jika saya mendefinisikan sesuatu dengan.factory('ServiceName')
atau.service('ServiceName')
resep dan ingin menggunakan salah satu metodenya dalam.config
blok, tetapkan parameternya sebagai ServiceNameProvider tetapi itu menghentikan aplikasi saya.Anda dapat menggunakan layanan $ inject untuk menyuntikkan layanan di konfigurasi Anda
Sumber: http://odetocode.com/blogs/scott/archive/2014/04/21/better-error-handling-in-angularjs.aspx
** Secara eksplisit meminta layanan dari modul lain menggunakan angular.injector **
Hanya untuk menguraikan jawaban kim3er , Anda dapat memberikan layanan, pabrik, dll tanpa mengubahnya ke penyedia, selama mereka termasuk dalam modul lain ...
Namun, saya tidak yakin apakah
*Provider
(yang dibuat secara internal oleh sudut setelah itu memproses layanan, atau pabrik) akan selalu tersedia (mungkin tergantung pada apa lagi yang dimuat pertama), karena sudut malas memuat modul.Perhatikan bahwa jika Anda ingin menyuntikkan kembali nilai-nilai yang harus diperlakukan sebagai konstanta.
Berikut ini cara yang lebih eksplisit, dan mungkin lebih andal untuk melakukannya + seorang plunker yang berfungsi
sumber
Menggunakan $ injector untuk memanggil metode layanan di config
Saya memiliki masalah serupa dan mengatasinya dengan menggunakan layanan $ injector seperti yang ditunjukkan di atas. Saya mencoba menyuntikkan layanan secara langsung tetapi berakhir dengan ketergantungan melingkar pada $ http. Layanan menampilkan modal dengan kesalahan dan saya menggunakan modal ui-bootstrap yang juga memiliki ketergantungan pada $ https.
sumber
Sebuah solusi yang sangat mudah dilakukan
Catatan : ini hanya untuk panggilan asynchrone, karena layanan tidak diinisialisasi pada eksekusi konfigurasi.
Anda bisa menggunakan
run()
metode. Contoh:Kode Anda:
sumber
Yah, saya sedikit berjuang dengan yang satu ini, tetapi saya benar-benar melakukannya.
Saya tidak tahu apakah jawabannya sudah usang karena beberapa perubahan sudut, tetapi Anda dapat melakukannya dengan cara ini:
Ini adalah layanan Anda:
Dan ini konfigurasi
sumber
Cara termudah:
$injector = angular.element(document.body).injector()
Kemudian gunakan itu untuk menjalankan
invoke()
atauget()
sumber