Bisakah saya menyuntikkan layanan ke arahan di AngularJS?

234

Saya mencoba menyuntikkan layanan ke arahan seperti di bawah ini:

 var app = angular.module('app',[]);
 app.factory('myData', function(){
     return {
        name : "myName"
     }
 });
 app.directive('changeIt',function($compile, myData){
    return {
            restrict: 'C',
            link: function (scope, element, attrs) {
                scope.name = myData.name;
            }
        }
 });

Tapi ini mengembalikan saya kesalahan Unknown provider: myDataProvider. Bisakah seseorang melihat kode dan memberi tahu saya jika saya melakukan sesuatu yang salah?

Pengecualian
sumber

Jawaban:

388

Anda dapat melakukan injeksi pada Arahan, dan sepertinya itu dilakukan di tempat lain.

app.directive('changeIt', ['myData', function(myData){
    return {
        restrict: 'C',
        link: function (scope, element, attrs) {
            scope.name = myData.name;
        }
    }
 }]);
Grendian
sumber
13
Saya pikir ini adalah solusi yang lebih baik karena berfungsi bahkan setelah mengecilkan kode Anda.
czerasz
5
Saya harus menambahkan '_myData = myData' sebelum return {} dan kemudian merujuk objek sebagai _myData di dalam fungsi tautan.
Jelling
Terima kasih @Jelling. Saya harus melakukan hal yang sama. Saya ingin tahu apakah ada orang di luar sana yang bisa memberi tahu kami alasannya ...?
sfletche
6
ada alasan khusus untuk menyuntikkan $ compile dalam arahan? sepertinya tidak digunakan dimanapun.
gru
4
Apakah ada solusi untuk menyuntikkan jika Anda ingin membuat fungsi tautan di luar arahan panggilan?
ThinkBonobo
19

Ubah definisi arahan Anda dari app.modulemenjadi app.directive. Terlepas dari itu semuanya terlihat baik-baik saja. Btw, sangat jarang Anda harus menyuntikkan layanan ke arahan. Jika Anda menyuntikkan layanan (yang biasanya merupakan sumber data atau model) ke dalam arahan Anda (yang merupakan bagian dari tampilan), Anda membuat sambungan langsung antara tampilan dan model Anda. Anda harus memisahkannya dengan menghubungkannya menggunakan pengontrol.

Itu bekerja dengan baik. Saya tidak yakin apa yang Anda lakukan itu salah. Ini adalah sebagian kerjanya.

http://plnkr.co/edit/M8omDEjvPvBtrBHM84Am

Ganaraj
sumber
Bisakah Anda memberikan contoh tolong
Pengecualian
@Exception Bisakah Anda memasukkan kode ke dalam biola? Saya dapat melihat dan melihat mengapa kode Anda tidak berfungsi dan mungkin membantu Anda memperbaikinya.
ganaraj
@Exception menambahkan plunk yang berfungsi yang menunjukkan kode berfungsi.
ganaraj
3
Saya baru saja menemukan sesuatu: Jika Anda mendefinisikan injeksi dalam parameter fungsi, function($location) { ...tetapi tidak benar-benar merujuk ke $locationdalam fungsi, AngularJS tidak akan melakukan injeksi. Satu-satunya waktu Anda akan melihat perilaku ini ada di dalam debugger.
Walter Stabosz
13
Saya tidak yakin saya setuju dengan komentar Anda "ditambah". Kami telah memasangkan controller dan layanan secara global - kami tidak dapat secara programatik mengganti implementasi layanan saat runtime. Yang berarti pengontrol tunggal mendapat layanan tunggal. Namun - arahan memiliki konfigurasi per tag yang terisolasi pada halaman, sehingga berpotensi kami mengaktifkan layanan yang berbeda untuk instance arahan yang berbeda. Menurut saya ini kurang dipisahkan.
guy mograbi
11

Anda juga dapat menggunakan layanan $ inject untuk mendapatkan layanan apa pun yang Anda suka. Saya menemukan itu berguna jika saya tidak tahu nama layanan sebelumnya tetapi tahu antarmuka layanan. Misalnya arahan yang akan menyambungkan tabel ke titik akhir ngResource atau tombol hapus-rekam umum yang berinteraksi dengan titik akhir api apa pun. Anda tidak ingin menerapkan kembali arahan tabel untuk setiap pengontrol atau sumber data.

template.html

<div my-directive api-service='ServiceName'></div>

my-directive.directive.coffee

angular.module 'my.module'
  .factory 'myDirective', ($injector) ->
    directive = 
      restrict: 'A'
      link: (scope, element, attributes) ->
        scope.apiService = $injector.get(attributes.apiService)

sekarang layanan 'anonim' Anda sepenuhnya tersedia. Jika itu adalah ngResource misalnya, Anda dapat menggunakan antarmuka ngResource standar untuk mendapatkan data Anda

Sebagai contoh:

scope.apiService.query((response) ->
  scope.data = response
, (errorResponse) ->
  console.log "ERROR fetching data for service: #{attributes.apiService}"
  console.log errorResponse.data
)

Saya telah menemukan teknik ini sangat berguna ketika membuat elemen yang berinteraksi dengan titik akhir API khususnya.

Tyrone Wilson
sumber