uygulama yapılandırması, angular.js'de özel sağlayıcı içinde $ http kullanın


90

Ana soru - bu mümkün mü? Şanssız denedim ..

main app.js

...
var app = angular.module('myApp', ['services']);
app.config(['customProvider', function (customProvider) {

}]);
...

sağlayıcının kendisi

var services = angular.module('services', []);
services.provider('custom', function ($http) {
});

Ve bende böyle bir hata var:

Uncaught Error: Unknown provider: $http from services 

Herhangi bir fikir?

Teşekkürler!



dostum, evet bu doğru, ama ben app.configbölümden bahsediyorum
Kosmetika


Bu sınırlamayı da biliyorum ama sağlayıcı içinde bir şekilde bunun mümkün olduğunu düşündüm ..
Kosmetika

Yanıtlar:


158

Sonuç olarak:

  • Sen CAN NOT sağlayıcı yapılandırması bölümüne bir hizmet enjekte .
  • Sen CAN sağlayıcının hizmet başlatır bölümüne bir hizmet enjekte .

Detaylar:

Açısal çerçevenin 2 aşamalı bir başlatma süreci vardır:

FAZ 1: Yapılandırma

configAşama sırasında tüm sağlayıcılar başlatılır ve tüm configbölümler yürütülür. configBölümler sağlayıcı nesneleri yapılandırır ve bu nedenle sağlayıcı nesneler ile enjekte edilebilir kod içerebilir. Ancak, sağlayıcılar hizmet nesneleri için fabrikalar olduğundan ve bu aşamada sağlayıcılar tam olarak başlatılmadığından / yapılandırılmadığından -> bu aşamada sağlayıcıdan sizin için bir hizmet oluşturmasını isteyemezsiniz -> yapılandırma aşamasında kullanamazsınız / hizmetleri enjekte edin . Bu aşama tamamlandığında tüm sağlayıcılar hazırdır (yapılandırma aşaması tamamlandıktan sonra artık sağlayıcı yapılandırması yapılamaz).

FAZ 2: Çalıştır

runAşama sırasında tüm runbölümler yürütülür. Bu aşamada sağlayıcılar hazırdır ve hizmetler oluşturabilir -> runaşama sırasında hizmetleri kullanabilir / enjekte edebilirsiniz .

Örnekler:

1. enjekte $httpsağlayıcı başlatma işlevine hizmet OLACAK DEĞİL

//ERRONEOUS
angular.module('myModule').provider('myProvider', function($http) {
    // SECTION 1: code to initialize/configure the PROVIDER goes here (executed during `config` phase)
    ...

    this.$get = function() {
        // code to initialize/configure the SERVICE goes here (executed during `run` stage)

        return myService;
    };
});

$httpHizmeti configaşama sırasında yürütülen bir işleve enjekte etmeye çalıştığımız için bir hata alacağız:

Uncaught Error: Unknown provider: $http from services 

Bu hatanın aslında söylediği şey $httpProvider, $httphizmeti oluşturmak için kullanılanın henüz hazır olmadığıdır (çünkü hala configaşamadayız).

2. $httpHizmetin hizmet başlatma işlevine enjekte edilmesi ÇALIŞACAKTIR :

//OK
angular.module('myModule').provider('myProvider', function() {
    // SECTION 1: code to initialize/configure the PROVIDER goes here (executed during `config` phase)
    ...

    this.$get = function($http) {
        // code to initialize/configure the SERVICE goes here (executed during `run` stage)

        return myService;
    };
});

Şu anda hizmeti, runaşama sırasında yürütülen hizmet başlatma işlevine enjekte ettiğimiz için bu kod çalışacaktır.


63
İyi cevap, ancak yapılandırma sırasında hizmetleri enjekte etmenin nasıl mümkün olmadığını açıklasa da, yapılandırma sırasında nasıl HTTP POST / GET yapılacağını açıklamıyor. Bu, bir API tarafından sağlanan değerler kullanılarak yapılandırılan uygulamalar için önemlidir.
Sean O'Dell

3
@bebraw & Kosmetika - Yapılandırma aşamasında talep etmeniz gerektiğini düşündüğüm tek şey bir tür ayar nesnesidir. Belki API uç noktasını, kullanıcı bilgilerini, kullanıcının yerel ayarlarını ve dil ayarlarını vb. İçerir. Durum buysa, bu bilgiyi bir şekilde javascript kaynağına dahil etmenizi öneririm. Index.html'de sunucu tarafı oluşturmayı kullanarak uygulamanız başlatılmadan önce kullanılabilir olmaları için birkaç ayarı kullanabilirsiniz. Diğer her şey, başlangıçtan sonra nasıl yapılacağını
Sean Clark Hess

2
@Sean: HTTP POST / GET nasıl yapılır, OP'lerin sorusundan farklı bir sorudur (Yapılandırma aşamasında $ http kullanmak mümkün müdür?) Ve muhtemelen ayrı bir gönderi gerektirir; Angular'ın yapılandırma aşamasının eşzamanlı yapısı nedeniyle, yapılandırma kodunuza sunucu tarafı verileri sağlamanın iyi bir yolu, bunu sunucu tarafı oluşturma sırasında HTML sayfanızda bir javascript nesnesi olarak işlemektir (örn. <script>var config = <% = mySettings.toJson() %>;</script>). Bu, PHP için Smarty, Python için Jinja2, NodeJS için Nunchucks, vb. Gibi bir şablon oluşturma motoru kullanılarak yapılabilir.
Trevor

4
@threed: Yapılandırma verilerini doğrudan sunucudaki HTML veya js'ye eklemek, yalnızca istemci kodunuz aynı sunucudan geliyorsa çalışır. CORS ile, istemci kodunun farklı bir sunucudan sunulması ve verilerin ayrı sunuculardan sunulması artık mümkün (ve çok arzu edilir). Bu gibi durumlarda, yapılandırma verilerini HTTP kullanarak almamız gerekir.
Bernard

4
Bu bir cevap olmakla birlikte sorulan sorunun cevabı değildir.
Eric

64

Bu size biraz avantaj sağlayabilir:

var initInjector = angular.injector(['ng']);
var $http = initInjector.get('$http');

Ancak dikkatli olun, başarı / hata geri aramaları sizi uygulamanın başlangıcı ile sunucu yanıtı arasında bir yarış durumunda tutabilir.


6
Sağlayıcım için "kabul edilen cevap" başarısız oldu ... Umutsuzca bu işe yaramaya çalışırken 2 gün boyunca hayal kırıklığı yaşadım. Yaklaşımınız hemen işe yaradı.
Dave Alperovich

Burada oluşturulan örneğin "gerçek" hizmet tekli olup olmadığını veya Angular gerçek enjektör sihrini yaptığında atılan hizmetin yalnızca bir örneği olup olmadığını açıklayabilir misiniz?
Eric

Eric, bunu şu anda teyit edemiyorum. Bununla birlikte, genellikle yaptığım şey (varsa) angular.injector(['mymodule'])- ancak bu yaklaşımı $httphizmet için kullanıp kullanamayacağınızdan emin değilim . Gerçi sahip olduğumu söylemek istiyorum. Bunun yardımcı olup olmadığından emin değilim: - /
Cody

2
Kabul edilen cevap bu olmalıdır. Bunu çalıştırmaya çalışırken iyilik için mücadele ettim ve bu yaklaşım sorunumu hemen çözdü. Bunun çok yaygın bir sorun olabileceğini düşünüyorum. Teşekkürler @Cody
iamdash

5
Kabul edilen çözümün sağlayıcıda $ http kullanmak için çalışmadığını onaylıyorum. Ancak @Cody'nin cevabı işe yarıyor
Dino

1

Bu eski bir soru, kütüphanenin temel kapasitesine güvenmek istiyorsak bazı tavuk yumurtası olayımız var gibi görünüyor.

Problemi temel bir yoldan çözmek yerine, yaptığım şey by-pass oldu. Tüm vücudu saran bir yönerge oluşturun. Örn.

<body ng-app="app">
  <div mc-body>
    Hello World
  </div>
</body>

Şimdi mc-bodyoluşturmadan önce (bir kez) başlatılması gerekiyor, örn.

link: function(scope, element, attrs) {
  Auth.login().then() ...
}

Auth bir hizmet veya sağlayıcıdır, ör.

.provider('Auth', function() {
  ... keep your auth configurations
  return {
    $get: function($http) {
      return {
        login: function() {
          ... do something about the http
        }
      }
    }
  }
})

Bana öyle geliyor ki, önyükleme sırası üzerinde denetimim var, bu, normal önyükleme tüm sağlayıcı yapılandırmasını çözdükten ve sonra mc-bodyyönergeyi başlatmaya çalıştıktan sonra .

Ve bu yönerge bana yönlendirmenin önünde olabilir, çünkü yönlendirme aynı zamanda bir yönerge ile de enjekte edilir. <ui-route />. Ama bu konuda yanılıyor olabilirim. Biraz daha araştırılması gerekiyor.


Lütfen çözümünüzü detaylandırır mısınız?
Mark

-2

"Herhangi Bir Fikriniz Var mı?" Sorunuza yanıt olarak "evet" ile yanıt verirdim. Ama bekleyin, dahası var!

Yapılandırmada sadece JQuery'yi kullanmanızı öneririm. Örneğin:

var app = angular.module('myApp', ['services']);
app.config(['$anyProvider', function ($anyProvider) {
    $.ajax({
        url: 'www.something.com/api/lolol',
        success: function (result) {
            $anyProvider.doSomething(result);
        }
    });
}]);

Başarı geri aramasında $ customProvider, dahili bir sağlayıcıymış gibi $ 'ı içerir.
Jeff Fischer

1
Benim bir karışımım olduğu konusunda haklısın, değil- $. Hepsini $ olacak şekilde güncelledim.
Suamere
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.