"Yakalanmamış Hata: [$ enjektör: unpr]" dağıtımdan sonra köşeli


99

Dev makinemde gayet iyi çalışan oldukça basit bir Angular uygulamam var, ancak bu hata mesajını (tarayıcı konsolunda) dağıttıktan sonra başarısız oluyor:

Uncaught Error: [$injector:unpr] http://errors.angularjs.org/undefined/$injector/unpr?p0=tProvider%20%3C-%20t%20%3C-%20%24http%20%3C-%20%24compile

Bunun dışında başka mesaj yok. Sayfa ilk yüklendiğinde olur.

ASP.NET MVC5, Angular 1.2RC3 çalıştırıyorum ve git aracılığıyla Azure'a gönderiyorum.

Google'da ilginç bir şey ortaya çıkmadı.

Herhangi bir öneri?

DÜZENLE:

TypeScript kullanıyorum ve bağımlılıklarımı $injectdeğişkenle tanımlıyorum , örneğin:

export class DashboardCtrl {

    public static $inject = [
        '$scope',
        '$location',
        'dashboardStorage'
    ];

    constructor(
        private $scope: IDashboardScope,
        private $location: ng.ILocationService,
        private storage: IDashboardStorage) {
    }
}

Küçültme sırasında ortaya çıkan ve bu hataya neden olabilecek yerel değişken yeniden adlandırma sorunlarının üstesinden gelinmesi gerektiğine (veya amaçlandığına) inanıyorum.

Bununla birlikte, açıkça küçültme süreciyle bir ilgisi var, çünkü geliştirici BundleTable.EnableOptimizations = truemakinemi kurduğumda onu yeniden üretebiliyorum.

Yanıtlar:


165

Bağlantınızı izlerseniz, hatanın $ enjektörün bağımlılıklarınızı çözememesinden kaynaklandığını söyler. Bu, javascript küçültüldüğünde / çirkinleştirildiğinde / üretim için ona yaptığınız her ne olursa olsun açısal ile ilgili yaygın bir sorundur.

Sorun, örneğin bir denetleyiciniz olduğunda ortaya çıkar;

angular.module("MyApp").controller("MyCtrl", function($scope, $q) {
  // your code
})

Minyatürleştirme değişir $scopeve $qaçısal olarak ne enjekte edileceğini söylemeyen rastgele değişkenlere dönüşür. Çözüm, bağımlılıklarınızı şöyle bildirmektir:

angular.module("MyApp")
  .controller("MyCtrl", ["$scope", "$q", function($scope, $q) {
  // your code
}])

Bu, sorununuzu çözmelidir.

Tekrarlamak gerekirse, söylediğim her şey hata mesajının size sağladığı bağlantıda.


2
Bağlantıyı gerçekten ziyaret etme öneriniz için teşekkürler - bunun benim yararıma bir şey değil, bazı dahili yapaylık olduğunu varsaymıştım. Görünüşe göre, tüm bağımlılıklarımı $injectsizin önerdiğiniz şekilde eşdeğer olduğuna inandığım genel değişken aracılığıyla tanımlıyorum (bkz. Docs.angularjs.org/guide/di ). Sorumu güncelleyeceğim.
Ken Smith

2
Bununla birlikte, geliştirici makinemde ( BundleTable.EnableOptimizations = true;) ASP.NET MVC küçültmelerini zorladığım zaman sorunu yeniden oluşturabildiğim için küçültme işlemiyle açıkça bir ilgisi var . Bakmaya devam ediyorum.
Ken Smith

Tamam, anladım. DI yaptığım ve unuttuğum başka bir yer daha vardı ve küçültme sürecinde altüst oluyordu. Teşekkürler, bu doğru cevaptı.
Ken Smith

Ayrıca, bunu sizin için otomatik olarak işleyecek bir paket vardır ve buna ngmin adı verilir ve buna karşılık gelen bir mücevher, ngmin-rails olarak adlandırılır .
bradleygriffith

2
@RyanTuck - Başka bir deyişle, küçültülmemiş kodla, Angular sadece işlevlerinizdeki değişken adlarına bakabilir ve neyin enjekte edilmesi gerektiği konusunda iyi bir tahmin yapabilir. Ancak küçültülmüş kodla, değişken adlarının tümü karıştırılır, bu nedenle, neyin enjekte edileceğini bilmek için başka bir mekanizmaya (kod küçültüldüğünde değişmeyen bir mekanizmaya) ihtiyaç duyar. $ İnject dizisi ve diğer mekanizmalar burada devreye giriyor.
Ken Smith

13

Ben de aynı problemle karşılaştım, ancak denetleyici tanımlarım yukarıdakinden biraz farklı görünüyordu. Şu şekilde tanımlanan kontrolörler için:

function MyController($scope, $http) {
    // ...
}

Bildirimden sonra, denetleyici başlatıldığında hangi nesnelerin enjekte edileceğini belirten bir satır ekleyin:

function MyController($scope, $http) {
    // ...
}
MyController.$inject = ['$scope', '$http'];

Bu onu küçültmeyi güvenli kılar.


11

Bu sorun, denetleyici veya yönerge bir bağımlılıklar ve işlev dizisi olarak belirtilmediğinde ortaya çıkar. Örneğin

angular.module("appName").directive('directiveName', function () {
    return {
        restrict: 'AE',
        templateUrl: 'calender.html',
        controller: function ($scope) {
            $scope.selectThisOption = function () {
                // some code
            };
        }
    };
});

Küçültüldüğünde denetleyici işlevine iletilen '$ kapsam' tek harfli bir değişken adı ile değiştirilir. Bu, bağımlılığın açısal ipuçlarını ortadan kaldıracaktır. Bunu önlemek için bağımlılık adını işlevle birlikte bir dizi olarak iletin.

angular.module("appName").directive('directiveName', function () {
    return {
        restrict: 'AE',
        templateUrl: 'calender.html'
        controller: ['$scope', function ($scope) {
            $scope.selectThisOption = function () {
                // some code
            };
        }]
    };
});

10

Açısal uygulama \ kaynaklar \ yönergeleri ve diğer şeyler için dosyaları ayırdıysanız, açısal uygulama paketinizin küçültülmesini şu şekilde devre dışı bırakabilirsiniz (paket yapılandırma dosyanızda ScriptBundle () yerine yeni Bundle () kullanın):

bundles.Add(
new Bundle("~/bundles/angular/SomeBundleName").Include(
               "~/Content/js/angular/Pages/Web/MainPage/angularApi.js",
               "~/Content/js/angular/Pages/Web/MainPage/angularApp.js",
               "~/Content/js/angular/Pages/Web/MainPage/angularCtrl.js"));

Ve açısal uygulama, paket içinde değiştirilmemiş olarak görünecektir.


Performans hakkında hangisi daha iyi? Bundle () veya ScriptBundle ()?
Thomas.Benz

@ Thomas.Benz Bundle () kullanımı yalnızca komut dosyalarınız için küçültmeyi devre dışı bırakır. Buradaki sorun, ScriptBundle () bazı Angular komut dosyalarını küçültüldüğünde, işlev adlarını kısaltması ve diğer ilgili işleri yapmasıdır. Ve Angular, bazı dahili bağımlılık enjeksiyonları veya bunun gibi bir şey yapmaya çalıştığında, bunun için uygun işlevleri bulamadı, çünkü adları özel bir şekilde değiştirildi ('SuperController'den' s 'veya başka bir şeye gibi). Bu nedenle, açısal komut dosyalarını değiştirmeden bırakmak veya küçültme için varsayılan olan yerine başka bir kitaplığı kullanmaya çalışmak daha iyidir.
Schnapz

1

Açısal uygulama \ kaynaklar \ yönergeleri ve diğer şeyler için dosyaları ayırdıysanız, açısal uygulama paketinizin küçültülmesini şu şekilde devre dışı bırakabilirsiniz (paket yapılandırma dosyanızda ScriptBundle () yerine yeni Bundle () kullanın):


0

$ Http, $ kapsam hizmetlerini denetleyici işlevine ekleyin, bazen eksikse bu hatalar oluşur.


0

Ben de aynı sorunu yaşadım ama sorun farklıydı, bir servis oluşturmaya ve buna parametre olarak $ kapsam geçmeye çalışıyordum.
Bu bağlantının belgelerinin dediği gibi, bu hatayı almanın başka bir yolu da budur:

Denetleyici veya yönerge olmayan herhangi bir şeye, örneğin bir hizmete bir kapsam nesnesi enjekte etmeye çalışmak da bir Bilinmeyen sağlayıcı: $ kapsamProvider <- $ kapsam hatası atar. Bu, bir denetleyiciyi yanlışlıkla hizmet olarak kaydettirirse olabilir, örn .:

angular.module('myModule', [])
       .service('MyController', ['$scope', function($scope) {
        // This controller throws an unknown provider error because
        // a scope object cannot be injected into a service.
}]);
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.