Bir işlevi açısal olarak her denetleyicide kullanılabilir hale getirebilir miyim?


191

Beyannamemin fooherhangi bir yerinden arayabileceğim bir yardımcı programım varsa ng-app. Modül kurulumumda global olarak erişebileceğim bir yol var mı veya her denetleyicideki kapsama eklemem gerekiyor mu?


Bu konuda% 100 emin değilim, ama bunu modülünüzde de şu şekilde tanımlayabilirsiniz: module.value('myFunc', function(a){return a;});ve sonra denetleyicilerinize ada göre enjekte edebilirsiniz. (Bir hizmet yapmaktan kaçınmak istiyorsa)
user2173353

Yani her denetleyiciye manuel olarak eklemem gerekiyor. $ rootScope neredeyse 2 yıl önce yapmak istediğim şey için gitmenin yoludur =)
Ludwig Magnusson

TAMAM. :) İzole kapsamdaki direktifleri düz kontrolörlerden daha sık kullanıyorum ve yine de her şeyi enjekte etmem gerekiyor. Bu sağladığı modüler kod stilini seviyorum. Ayrıca, hiçbir şekilde üst kapsamlarla uğraşmak zorunda kalmazsınız ve kapsam değişkenlerinizin nereden geldiğini çok fazla araştırmanız gerekmez. :)
user2173353

Yanıtlar:


290

Temel olarak iki seçeneğiniz vardır, ya bir hizmet olarak tanımlayın ya da kök kapsamınıza yerleştirin. Kök kapsamını kirletmemek için bir hizmet vermenizi öneririm. Bir hizmet oluşturursunuz ve bunu denetleyicinizde şu şekilde kullanılabilir hale getirirsiniz:

<!doctype html>
<html ng-app="myApp">
<head>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="http://code.angularjs.org/1.1.2/angular.min.js"></script>
    <script type="text/javascript">
    var myApp = angular.module('myApp', []);

    myApp.factory('myService', function() {
        return {
            foo: function() {
                alert("I'm foo!");
            }
        };
    });

    myApp.controller('MainCtrl', ['$scope', 'myService', function($scope, myService) {
        $scope.callFoo = function() {
            myService.foo();
        }
    }]);
    </script>
</head>
<body ng-controller="MainCtrl">
    <button ng-click="callFoo()">Call foo</button>
</body>
</html>

Bu sizin için bir seçenek değilse, bunu kök kapsamına şu şekilde ekleyebilirsiniz:

<!doctype html>
<html ng-app="myApp">
<head>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="http://code.angularjs.org/1.1.2/angular.min.js"></script>
    <script type="text/javascript">
    var myApp = angular.module('myApp', []);

    myApp.run(function($rootScope) {
        $rootScope.globalFoo = function() {
            alert("I'm global foo!");
        };
    });

    myApp.controller('MainCtrl', ['$scope', function($scope){

    }]);
    </script>
</head>
<body ng-controller="MainCtrl">
    <button ng-click="globalFoo()">Call global foo</button>
</body>
</html>

Bu şekilde, tüm globalFoo()şablonlarınız denetleyiciden şablona aktarmak zorunda kalmadan çağrı yapabilir.


5
İlk çözümde, tonlarca foo()fonksiyon varsa ne olur ? $scope.callFoo()Her biri için bir sargı yapmak çok fazla iş. Şablonda kullanılabilmesi için bir kütüphanenin tüm işlevlerini kapsama nasıl ekleyebilirim ? Şablonumda kullanılabilir olmasını istediğim büyük bir birim dönüştürme kitaplığım var.
AlexStack

3
Benim de sorum. Bunu denedim ve işe yarıyor: $scope.callFoo = myService.foo;kullanmak istediğiniz her yerde yeni bir sarıcı oluşturmak yerine söyleyerek "ekleyebilirsiniz" .
Tesisatçı

1
Yardımınız için teşekkürler, uygulamam boyunca dil değiştirme işlevini nasıl kullanıma sunacağımı merak ediyordum ve $ rootScope işi yaptı. Çeviri modülünü uygulamadan uzak tutmak istedim, böylece diğer uygulamalara da takabiliyorum.
Paulo Pedroso

Bir hizmet içinde birden çok işleve sahip olmayı planlamıyorsanız, bu özel durum için bir Fabrika yerine Açısal Değer kullanmanızı öneririm. Tek bir işlevse, bir Değer yapın.
Nicholas Blasgen

Hata aldım: [$ injector: unpr]
Mark Thien

53

Bunları da birleştirebilirsiniz sanırım:

<!doctype html>
<html ng-app="myApp">
<head>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="http://code.angularjs.org/1.1.2/angular.min.js"></script>
    <script type="text/javascript">
        var myApp = angular.module('myApp', []);

        myApp.factory('myService', function() {
            return {
                foo: function() {
                    alert("I'm foo!");
                }
            };
        });

        myApp.run(function($rootScope, myService) {
            $rootScope.appData = myService;
        });

        myApp.controller('MainCtrl', ['$scope', function($scope){

        }]);

    </script>
</head>
<body ng-controller="MainCtrl">
    <button ng-click="appData.foo()">Call foo</button>
</body>
</html>

7
Bence bu, @Praym'in cevabı ile doğrulanan doğru cevap olmalı. 10 farklı denetleyicide bir hizmet bağımlılığı belirtmek mantıklı değildir.
jvannistelrooy

Hizmet CRUD özelliklerini / değişkenlerini $rootScope?
jezmck

44

İlk yaklaşım 'açısal benzeri' yaklaşım olarak savunulsa da, bunun ek yük getirdiğini hissediyorum.

Bu myservice.foo işlevini 10 farklı denetleyicide kullanmak isteyip istemediğimi düşünün. Bu 'myService' bağımlılığını ve sonra on tanesinde $ scope.callFoo scope özelliğini belirtmem gerekecek. Bu sadece bir tekrarlamadır ve bir şekilde KURU ilkesini ihlal eder.

Oysa, $ rootScope yaklaşımını kullanırsam, bu global işlevi gobalFoo'yu yalnızca bir kez belirtirim ve kaç tane olursa olsun, gelecekteki tüm denetleyicilerimde kullanılabilir olacaktır.


5
Denetleyicilerin bu küresel servis çağrısını aldıkları 'belgelemede' bir miktar değer olabilir. Eğer kontrolörlerinizden birini başka bir uygulamaya soksaydınız, bu küresel fonksiyonun nereden geldiği daha az açık olurdu. Yine de tartışmanızı tanıdığını duydum.
Matthew Payne

Sadece görünümden çağırmanız gerekiyorsa kapsama konulmalıdır. Denetleyicide, doğrudan hizmetten arayabilirsiniz.
mcv

10
Bu bir cevap değil
Elliott

$ rootScope değişkeni sayfa yenilemesinde her zaman null olur, bu durumda işlevi alamazsınız. Bu yüzden hizmeti enjekte etmek ve referansını uygulamada kullanmak iyidir.
Ehsan Hafeez

4

AngularJs sadece sizin gibi sorunlar için " Hizmetler " ve " Fabrikalar " vardır. Bunlar Kontrolörler, Direktifler, Diğer Hizmetler veya diğer herhangi bir açısaljs bileşenleri arasında küresel bir şey için kullanılır .. Fonksiyonları tanımlayabilir, veri saklayabilir, hesaplama fonksiyonları yapabilir veya her neyse içeride istediğiniz Hizmetleri ve onları olduğu gibi angularjs Bileşenlerinin kullandığımız Küresel .like

angular.module('MyModule', [...])
  .service('MyService', ['$http', function($http){
    return {
       users: [...],
       getUserFriends: function(userId){
          return $http({
            method: 'GET',
            url: '/api/user/friends/' + userId
          });
       }
       ....
    }
  }])

daha fazlasına ihtiyacınız varsa

Neden AngularJs Hizmetlerine ve Fabrikalarına İhtiyacımız Olduğu Hakkında Daha Fazla Bilgi


0

Açısal için biraz daha yeniyim ama yararlı bulduğum (ve oldukça basit), yine de tüm sayfalarda erişmem gereken küresel değişkenlerle yerel komut dosyasından önce sayfama yüklediğim global bir komut dosyası oluşturdum. Bu komut dosyasında, "globalFunctions" adlı bir nesne oluşturdum ve global olarak özellikler olarak erişmem gereken işlevleri ekledim. örn globalFunctions.foo = myFunc();. Sonra, her yerel komut dosyasında yazdım $scope.globalFunctions = globalFunctions;ve global komut dosyasında globalFunctions nesnesine eklediğim herhangi bir işleve anında erişebiliyorum.

Bu biraz geçici bir çözümdür ve size yardımcı olduğundan emin değilim ama birçok fonksiyonum olduğu için kesinlikle bana yardımcı oldu ve her sayfaya hepsini ekleyen bir acıydı.


1
Neden merak ediyorum? Ben yeniyim ve profesyonellerden bilmek istiyorum.
Izzy

Bana çalışan bir çözüm gibi görünüyor. Kapsamınızın yeterince izole edildiğinden emin olmak için savunacağım tek şey, global bir kök Javascript yardımcı programı sınıfı oluşturmak ve yanlışlıkla diğer bazı işlev adlarına basmamanız için yardımcı program yöntemlerinizi asmaktır. Angular tarafından enjekte edilen şeylerin engin denizi.
JE Carter II

Unutulmaması gereken bir nokta ve belki de bunun neden reddedildiğini, işlev çağrılarınız derleme zamanında çözülmeyeceği için .ts modüllerinizi değil, yalnızca şablonlarınızda bu işlevleri kullanabilirsiniz. Bunu "açısal" şekilde yapmanın nedeni budur. Ancak, sadece şablonlarınıza dekoratörler ve benzeri şeyler eklemek istiyorsanız, küresel bir yardımcı program dosyası basit ve iyidir.
JE Carter II
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.