AngularJS: Eşzamansız verilerle hizmeti başlat


475

Bazı eşzamansız verilerle başlatmak istediğiniz bir AngularJS hizmetim var. Bunun gibi bir şey:

myModule.service('MyService', function($http) {
    var myData = null;

    $http.get('data.json').success(function (data) {
        myData = data;
    });

    return {
        setData: function (data) {
            myData = data;
        },
        doStuff: function () {
            return myData.getSomeData();
        }
    };
});

Açıkçası bu işe yaramaz çünkü bir şey geri doStuff()dönmeden önce aramaya çalışırsa myDatabir boş işaretçi istisnası alırım. Burada ve burada sorulan diğer soruları okuyarak söyleyebildiğim kadarıyla birkaç seçeneğim var, ancak hiçbiri çok temiz görünmüyor (belki de bir şey eksikim):

"Run" ile Kurulum Hizmeti

Uygulamamı kurarken bunu yapın:

myApp.run(function ($http, MyService) {
    $http.get('data.json').success(function (data) {
        MyService.setData(data);
    });
});

Sonra benim hizmet şöyle görünecektir:

myModule.service('MyService', function() {
    var myData = null;
    return {
        setData: function (data) {
            myData = data;
        },
        doStuff: function () {
            return myData.getSomeData();
        }
    };
});

Bu zaman zaman işe yarar, ancak eşzamansız veriler her şeyin başlatılması için gereken süreden daha uzun sürerse, aradığımda boş bir işaretçi istisnası alıyorum doStuff()

Vaat nesneleri kullanma

Bu muhtemelen işe yarar. MyService dediğim her yerde tek dezavantajı doStuff () bir söz verdiğini ve tüm kodun thensöz ile etkileşime girmek için bize bilmek zorunda kalacak . Ben sadece benim uygulama yüklemeden önce myData geri kadar beklemek istiyorum.

Manuel Önyükleme

angular.element(document).ready(function() {
    $.getJSON("data.json", function (data) {
       // can't initialize the data here because the service doesn't exist yet
       angular.bootstrap(document);
       // too late to initialize here because something may have already
       // tried to call doStuff() and would have got a null pointer exception
    });
});

Global Javascript Var JSON'umu doğrudan global Javascript değişkenine gönderebilirim:

HTML:

<script type="text/javascript" src="data.js"></script>

data.js:

var dataForMyService = { 
// myData here
};

Sonra başlatırken kullanılabilir olacaktır MyService:

myModule.service('MyService', function() {
    var myData = dataForMyService;
    return {
        doStuff: function () {
            return myData.getSomeData();
        }
    };
});

Bu da işe yarayacaktı, ama sonra kötü kokan küresel bir javascript değişkenim var.

Bunlar benim tek seçeneklerim mi? Bu seçeneklerden biri diğerlerinden daha mı iyi? Bunun oldukça uzun bir soru olduğunu biliyorum, ama tüm seçeneklerimi keşfetmeye çalıştığımı göstermek istedim. Herhangi bir rehberlik büyük mutluluk duyacağız.


açısal - bootstrap , bir sunucudan veri çekmek $http, daha sonra verileri bir servise kaydetmek, ardından bir uygulamayı önyüklemek için eşzamansız olarak kod boyunca yürür .
Steven Wexler

Yanıtlar:


327

Bir baktın mı $routeProvider.when('/path',{ resolve:{...}? Söz yaklaşımını biraz daha temiz hale getirebilir:

Hizmetinizde bir söz verin:

app.service('MyService', function($http) {
    var myData = null;

    var promise = $http.get('data.json').success(function (data) {
      myData = data;
    });

    return {
      promise:promise,
      setData: function (data) {
          myData = data;
      },
      doStuff: function () {
          return myData;//.getSomeData();
      }
    };
});

resolveRota yapılandırmanıza ekleyin :

app.config(function($routeProvider){
  $routeProvider
    .when('/',{controller:'MainCtrl',
    template:'<div>From MyService:<pre>{{data | json}}</pre></div>',
    resolve:{
      'MyServiceData':function(MyService){
        // MyServiceData will also be injectable in your controller, if you don't want this you could create a new promise with the $q service
        return MyService.promise;
      }
    }})
  }):

Tüm bağımlılıklar çözülmeden denetleyiciniz somutlaştırılmayacak:

app.controller('MainCtrl', function($scope,MyService) {
  console.log('Promise is now resolved: '+MyService.doStuff().data)
  $scope.data = MyService.doStuff();
});

Plnkr'de bir örnek yaptım: http://plnkr.co/edit/GKg21XH0RwCMEQGUdZKH?p=preview


1
Yanıtınız için çok teşekkür ederim! MyService kullanan çözüm haritasında zaten bir hizmetim olmasaydı benim için işe yarardı. Pistonunuzu durumumla güncelledim: plnkr.co/edit/465Cupaf5mtxljCl5NuF?p=preview . MyOtherService'ın MyService'in başlatılmasını beklemesinin bir yolu var mı?
testing123

2
Sanırım MyOtherService'deki vaatleri zincirleyecektim - dalma makinesini zincirleme ve bazı yorumlarla güncelledim - bu nasıl görünüyor? plnkr.co/edit/Z7dWVNA9P44Q72sLiPjW?p=preview
joakimbl

3
Bunu denedim ve hala bazı sorunlara rastladım çünkü 'MyService'e kadar beklemeniz gereken direktifler ve diğer denetleyicilerim var ($ routeProvider ile kullandığım denetleyici birincil, ikincil gezinme öğelerini işliyor ... yani' MyOtherService ') 'çözüldü. Denemeye devam edeceğim ve elimden gelen başarı ile güncelleyeceğim. Keşke sadece denetleyicilerimi ve yönergelerimi başlatmadan önce verilerin geri dönmesini bekleyebileceğim açısal bir kanca olsaydı. Yardımın için tekrar teşekkürler. Her şeyi saran bir ana denetleyicim olsaydı, bu işe yarardı.
testing123

43
Burada bir soru - resolveözelliği belirtilmeyen bir denetleyiciye nasıl atayacaksınız $routeProvider. Örneğin <div ng-controller="IndexCtrl"></div>,. Burada kontrolör açıkça belirtilir ve yönlendirme yoluyla yüklenmez. Böyle bir durumda, kontrolörün başlatılmasını nasıl erteler?
callmekatootie

19
Hmm, yönlendirme kullanmıyorsanız ne olacak? Bu, yönlendirmeyi kullanmadığınız sürece eşzamansız verilerle açısal bir uygulama yazamayacağınızı söylemek gibidir. Bir uygulamaya veri almanın önerilen yolu, senkronize olmayan bir şekilde yüklemektir, ancak birden fazla denetleyiciniz olduğunda ve hizmetleri atar atmaz, BOOM imkansızdır.
wired_in

88

Martin Atkins'in çözümüne dayanan, tam ve özlü bir saf açısal çözüm:

(function() {
  var initInjector = angular.injector(['ng']);
  var $http = initInjector.get('$http');
  $http.get('/config.json').then(
    function (response) {
      angular.module('config', []).constant('CONFIG', response.data);

      angular.element(document).ready(function() {
          angular.bootstrap(document, ['myApp']);
        });
    }
  );
})();

Bu çözüm, $ http hizmetini almak, yapılandırmayı istemek ve kullanılabilir olduğunda CONFIG adlı bir sabit içine enjekte etmek için kendi kendini yürüten anonim bir işlev kullanır.

Tamamen, belge hazır olana kadar bekler ve ardından Açısal uygulamayı önyükleriz.

Bu, belge hazır olduktan sonra yapılandırmayı getirmeyi erteleyen Martin çözümü üzerinde hafif bir gelişmedir. Bildiğim kadarıyla, bunun için $ http çağrısını geciktirmek için bir neden yoktur.

Birim Testi

Not: Kodunuz app.jsdosyanıza dahil edildiğinde birim sınama sırasında bu çözümün iyi çalışmadığını keşfettim . Bunun nedeni, JS dosyası yüklendiğinde yukarıdaki kodun hemen çalışmasıdır. Bu, test çerçevesinin (benim durumumda Yasemin) sahte bir uygulama sağlama şansı olmadığı anlamına gelir $http.

Tamamen memnun olmadığım çözüm, bu kodu index.htmldosyamıza taşımaktı , böylece Grunt / Karma / Jasmine birim test altyapısı onu görmedi.


1
'Küresel kapsamı kirletmeyin' gibi kurallara ancak kodumuzu daha iyi hale getirdikleri ölçüde (daha az karmaşık, daha sürdürülebilir, daha güvenli vb.) Uyulmalıdır. Bu çözümün verileri tek bir global değişkene yüklemekten daha iyi olduğunu göremiyorum. Neyi kaçırıyorum?
david004

4
İhtiyaç duyulan modüllerde 'CONFIG' sabitine erişmek için Angular'ın bağımlılık enjeksiyon sistemini kullanmanıza izin verir, ancak ihtiyaç duymayan diğer modülleri tıkama riskiniz yoktur. Örneğin, global bir 'config' değişkeni kullandıysanız, diğer 3. taraf kodlarının da aynı değişkeni arama olasılığı vardır.
JBCP

1
Ben açısal bir acemi değilim, İşte benim app yapılandırma modülü bağımlılığı nasıl çözüldü hakkında bazı notlar: gist.github.com/dsulli99/0be3e80db9b21ce7b989 ref: tutorials.jenkov.com/angularjs/… Bu çözüm için teşekkür ederiz.
dps

7
Aşağıdaki diğer manuel bootstrap çözümlerinden birinde bir yorumda belirtilmiştir, ancak düzgün bir şekilde açılmayan açısal bir acemi olarak, bunun düzgün çalışması için html kodunuzdaki ng-app yönergenizi silmeniz gerektiğini işaret edebilirim. - otomatik önyükleme (ng-app ile) bu manuel yöntemle değiştiriliyor. Ng uygulamasını çıkarmazsanız uygulama gerçekten işe yarayabilir, ancak konsolda çeşitli bilinmeyen sağlayıcı hataları görürsünüz.
IrishDubGuy

49

@XMLilley tarafından açıklanan yönteme benzer bir yaklaşım kullandım, ancak $httpyapılandırmayı yüklemek ve düşük düzeyli API'ler veya jQuery kullanmadan daha fazla başlatma yapmak gibi AngularJS hizmetlerini kullanma yeteneğine sahip olmak istedim .

kullanma resolve da bir seçenek değildi çünkü uygulamam başlatıldığında değerlerin module.config()bloklar halinde bile sabit olması gerekiyordu .

Yapılandırmayı yükleyen, gerçek uygulamada sabit olarak ayarlayan ve önyükleme yapan küçük bir AngularJS uygulaması oluşturdum.

// define the module of your app
angular.module('MyApp', []);

// define the module of the bootstrap app
var bootstrapModule = angular.module('bootstrapModule', []);

// the bootstrapper service loads the config and bootstraps the specified app
bootstrapModule.factory('bootstrapper', function ($http, $log, $q) {
  return {
    bootstrap: function (appName) {
      var deferred = $q.defer();

      $http.get('/some/url')
        .success(function (config) {
          // set all returned values as constants on the app...
          var myApp = angular.module(appName);
          angular.forEach(config, function(value, key){
            myApp.constant(key, value);
          });
          // ...and bootstrap the actual app.
          angular.bootstrap(document, [appName]);
          deferred.resolve();
        })
        .error(function () {
          $log.warn('Could not initialize application, configuration could not be loaded.');
          deferred.reject();
        });

      return deferred.promise;
    }
  };
});

// create a div which is used as the root of the bootstrap app
var appContainer = document.createElement('div');

// in run() function you can now use the bootstrapper service and shutdown the bootstrapping app after initialization of your actual app
bootstrapModule.run(function (bootstrapper) {

  bootstrapper.bootstrap('MyApp').then(function () {
    // removing the container will destroy the bootstrap app
    appContainer.remove();
  });

});

// make sure the DOM is fully loaded before bootstrapping.
angular.element(document).ready(function() {
  angular.bootstrap(appContainer, ['bootstrapModule']);
});

Buraya ( $timeoutyerine kullanmak yerine $http) buradan bakın: http://plnkr.co/edit/FYznxP3xe8dxzwxs37hi?p=preview

GÜNCELLEME

Aşağıda Martin Atkins ve JBCP tarafından açıklanan yaklaşımı kullanmanızı tavsiye ederim.

GÜNCELLEME 2

Birden fazla projede ihtiyacım olduğu için, bununla ilgilenen bir bower modülü yayınladım: https://github.com/philippd/angular-deferred-bootstrap

Arka uçtan veri yükleyen ve AngularJS modülünde APP_CONFIG adlı bir sabit ayarlayan örnek:

deferredBootstrapper.bootstrap({
  element: document.body,
  module: 'MyApp',
  resolve: {
    APP_CONFIG: function ($http) {
      return $http.get('/api/demo-config');
    }
  }
});


44

"Manuel bootstrap" durumu, bootstrap öncesinde manuel olarak bir enjektör oluşturarak Açısal servislere erişebilir. Bu ilk enjektör tek başına duracak (herhangi bir elemana bağlı olmayacak) ve sadece yüklü modüllerin bir alt kümesini içerecektir. İhtiyacınız olan tek şey temel Açısal hizmetler ise, sadece aşağıdakileri yüklemek yeterlidir ng:

angular.element(document).ready(
    function() {
        var initInjector = angular.injector(['ng']);
        var $http = initInjector.get('$http');
        $http.get('/config.json').then(
            function (response) {
               var config = response.data;
               // Add additional services/constants/variables to your app,
               // and then finally bootstrap it:
               angular.bootstrap(document, ['myApp']);
            }
        );
    }
);

Örneğin, module.constantverileri uygulamanızın kullanımına sunmak için bu mekanizmayı kullanabilirsiniz :

myApp.constant('myAppConfig', data);

Bu myAppConfigartık diğer tüm servisler gibi enjekte edilebilir ve özellikle yapılandırma aşamasında kullanılabilir:

myApp.config(
    function (myAppConfig, someService) {
        someService.config(myAppConfig.someServiceConfig);
    }
);

ya da daha küçük bir uygulama için, global konfigürasyonu, uygulama boyunca konfigürasyon formatı hakkındaki bilgileri yayma pahasına, doğrudan hizmetinize enjekte edebilirsiniz.

Tabii ki, buradaki zaman uyumsuz işlemler uygulamanın önyüklemesini engelleyeceği ve böylece şablonun derlenmesini / bağlanmasını ng-cloakengelleyeceğinden, ayrıştırılmamış şablonun çalışma sırasında görünmesini önlemek için yönergeyi kullanmak akıllıca olacaktır . Ayrıca, yalnızca AngularJS başlatılana kadar gösterilen HTML'yi sağlayarak DOM'da bir tür yükleme göstergesi de sağlayabilirsiniz:

<div ng-if="initialLoad">
    <!-- initialLoad never gets set, so this div vanishes as soon as Angular is done compiling -->
    <p>Loading the app.....</p>
</div>
<div ng-cloak>
    <!-- ng-cloak attribute is removed once the app is done bootstrapping -->
    <p>Done loading the app!</p>
</div>

Oluşturduğum tamamını, çalışma örneği örnek olarak statik bir JSON dosyasından yapılandırmasını yüklerken, Plunker bu yaklaşımın.


Belge hazır olana kadar $ http.get () ertelemeniz gerektiğini sanmıyorum.
JBCP

@JBCP evet, olayları değiştirirseniz, HTTP yanıtı döndürülene kadar belgenin hazır olmasını beklemememiz de doğru olur, muhtemelen HTTP'yi başlatabilme avantajı daha hızlı isteyin. DOM hazır olana kadar yalnızca bootstrap çağrısının beklemesi gerekir.
Martin Atkins

2
: Ben senin yaklaşımla bir kameriye modülü hazırlandı github.com/philippd/angular-deferred-bootstrap
philippd

@MartinAtkins, harika yaklaşımınızın Angular v1.1 + ile çalışmadığını gördüm. Angular'ın ilk sürümleri, uygulama önyükleninceye kadar "o zaman" ı anlamıyor gibi görünüyor. Plunk'ınızda
vkelman

16

Aynı sorun vardı: resolveNesneyi seviyorum , ama bu sadece ng-view içeriği için çalışıyor. Ya ng-view dışında var olan ve yönlendirme gerçekleşmeye başlamadan önce verilerle başlatılması gereken kontrolörleriniz varsa (üst düzey gezinme için diyelim)? Sadece bu işi yapmak için sunucu tarafında dolaşmayı nasıl önleyebiliriz?

Manuel bootstrap ve açısal sabit kullanın . Naif bir XHR, verilerinizi alır ve geri çağrısında açısal sorunlarınızla ilgilenen açısal önyükleme yaparsınız. Aşağıdaki örnekte, global bir değişken oluşturmanız bile gerekmez. Döndürülen veriler, enjektabl olarak sadece açısal kapsamda bulunur ve siz enjekte etmedikçe kontrolörler, hizmetler vb. (Yönlendirilmiş resolvebir görünüm için nesnenizin çıktısını denetleyiciye enjekte ettiğiniz kadar .) Daha sonra bu verilerle bir hizmet olarak etkileşim kurmayı tercih ederseniz, bir hizmet oluşturabilir, verileri enjekte edebilirsiniz ve hiç kimse daha akıllı olmayacaktır. .

Misal:

//First, we have to create the angular module, because all the other JS files are going to load while we're getting data and bootstrapping, and they need to be able to attach to it.
var MyApp = angular.module('MyApp', ['dependency1', 'dependency2']);

// Use angular's version of document.ready() just to make extra-sure DOM is fully 
// loaded before you bootstrap. This is probably optional, given that the async 
// data call will probably take significantly longer than DOM load. YMMV.
// Has the added virtue of keeping your XHR junk out of global scope. 
angular.element(document).ready(function() {

    //first, we create the callback that will fire after the data is down
    function xhrCallback() {
        var myData = this.responseText; // the XHR output

        // here's where we attach a constant containing the API data to our app 
        // module. Don't forget to parse JSON, which `$http` normally does for you.
        MyApp.constant('NavData', JSON.parse(myData));

        // now, perform any other final configuration of your angular module.
        MyApp.config(['$routeProvider', function ($routeProvider) {
            $routeProvider
              .when('/someroute', {configs})
              .otherwise({redirectTo: '/someroute'});
          }]);

        // And last, bootstrap the app. Be sure to remove `ng-app` from your index.html.
        angular.bootstrap(document, ['NYSP']);
    };

    //here, the basic mechanics of the XHR, which you can customize.
    var oReq = new XMLHttpRequest();
    oReq.onload = xhrCallback;
    oReq.open("get", "/api/overview", true); // your specific API URL
    oReq.send();
})

Şimdi, NavDatasabitiniz var. Devam edin ve bir denetleyiciye veya hizmete enjekte edin:

angular.module('MyApp')
    .controller('NavCtrl', ['NavData', function (NavData) {
        $scope.localObject = NavData; //now it's addressable in your templates 
}]);

Elbette, çıplak bir XHR nesnesi kullanmak, $httpJQuery'nin sizin için halledeceği bir dizi güzelliği ortadan kaldırır, ancak bu örnek en azından basit bir şey için özel bağımlılıklar olmadan çalışır get. İsteğiniz için biraz daha fazla güç istiyorsanız, size yardımcı olması için harici bir kütüphane yükleyin. Ancak $httpbu bağlamda açısal veya diğer araçlara erişmenin mümkün olduğunu düşünmüyorum .

(SO ilgili yayın )


8

Yapabileceğiniz şey, uygulama için .config dosyasında yol için çözüm nesnesi oluşturmak ve $ q (söz verilen nesne) işlevine ve bağlı olduğunuz hizmetin adına geçmek ve söz konusu öğedeki sözünü çözmek. Hizmette $ http için geri arama işlevi şöyle:

GÜZERGAH YAPILANDIRMASI

app.config(function($routeProvider){
    $routeProvider
     .when('/',{
          templateUrl: 'home.html',
          controller: 'homeCtrl',
          resolve:function($q,MyService) {
                //create the defer variable and pass it to our service
                var defer = $q.defer();
                MyService.fetchData(defer);
                //this will only return when the promise
                //has been resolved. MyService is going to
                //do that for us
                return defer.promise;
          }
      })
}

Açısal defer.resolve () çağrılıncaya kadar şablonu oluşturmaz veya denetleyiciyi kullanılabilir hale getirmez. Bunu hizmetimizde yapabiliriz:

HİZMET

app.service('MyService',function($http){
       var MyService = {};
       //our service accepts a promise object which 
       //it will resolve on behalf of the calling function
       MyService.fetchData = function(q) {
             $http({method:'GET',url:'data.php'}).success(function(data){
                 MyService.data = data;
                 //when the following is called it will
                 //release the calling function. in this
                 //case it's the resolve function in our
                 //route config
                 q.resolve();
             }
       }

       return MyService;
});

Artık MyService, data özelliğine atanan verilere sahip olduğuna ve route çözünürlük nesnesindeki vaat çözüldüğüne göre, rota için denetleyicimiz hayata geçer ve verileri hizmetten denetleyici nesnesine atayabiliriz.

KONTROLÖRÜ

  app.controller('homeCtrl',function($scope,MyService){
       $scope.servicedata = MyService.data;
  });

Artık denetleyici kapsamındaki tüm bağlarımız MyService kaynaklı verileri kullanabilecektir.


Daha fazla zamanım olduğunda bunu deneyeceğim. Bu, ngModules'de başkalarının yapmaya çalıştığı şeye benzer.
2013

1
Ben bu yaklaşımı seviyorum ve daha önce kullandım ama şu anda her biri önceden getirilmiş verilere bağlı olabilir veya olmayabilir birkaç yol var, bunu temiz bir şekilde yapmaya çalışıyorum. Bunun hakkında bir fikrin var mı?
ivarni

btw, önceden getirilmiş veri gerektiren her hizmetin başlatıldığında istekte bulunmasını ve bir söz vermesini ve daha sonra farklı yolların gerektirdiği hizmetlerle birlikte çözüm nesnelerini ayarlamasını sağlıyorum. Keşke daha az ayrıntılı bir yol olsaydı.
ivarni

1
@dewd Amaçladığım şey bu, ancak çözüm bloklarımı tekrarlamak zorunda kalmadan "tüm bu şeyleri hangi yolun yüklü olduğuna bakılmaksızın al" demenin bir yolu olsaydı çok tercih ederdim. Hepsinin bağımlı oldukları bir şey var. Ama bu büyük bir anlaşma değil, sadece biraz daha KURU hissediyorum :)
ivarni

2
Bu, resolveişlevi olan bir özellik ile bir nesne yapmak zorunda kaldım, sonlandırdığım rota . böylece sona erdiresolve:{ dataFetch: function(){ // call function here } }
aron.duby

5

Böylece bir çözüm buldum. Bir angularJS hizmeti oluşturdum, MyDataRepository adını vereceğiz ve bunun için bir modül oluşturdum. Sonra bu javascript dosyasını benim sunucu tarafı denetleyiciden hizmet:

HTML:

<script src="path/myData.js"></script>

Sunucu tarafı:

@RequestMapping(value="path/myData.js", method=RequestMethod.GET)
public ResponseEntity<String> getMyDataRepositoryJS()
{
    // Populate data that I need into a Map
    Map<String, String> myData = new HashMap<String,String>();
    ...
    // Use Jackson to convert it to JSON
    ObjectMapper mapper = new ObjectMapper();
    String myDataStr = mapper.writeValueAsString(myData);

    // Then create a String that is my javascript file
    String myJS = "'use strict';" +
    "(function() {" +
    "var myDataModule = angular.module('myApp.myData', []);" +
    "myDataModule.service('MyDataRepository', function() {" +
        "var myData = "+myDataStr+";" +
        "return {" +
            "getData: function () {" +
                "return myData;" +
            "}" +
        "}" +
    "});" +
    "})();"

    // Now send it to the client:
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.add("Content-Type", "text/javascript");
    return new ResponseEntity<String>(myJS , responseHeaders, HttpStatus.OK);
}

Sonra MyDataRepository enjekte edebilirim nereye ihtiyacım olursa:

someOtherModule.service('MyOtherService', function(MyDataRepository) {
    var myData = MyDataRepository.getData();
    // Do what you have to do...
}

Bu benim için harika çalıştı, ama eğer varsa, herhangi bir geri bildirime açıkım. }


Modüler yaklaşımınızı seviyorum. $ RouteScope veri isteyen hizmet için kullanılabilir olduğunu ve $ http.success geri arama veri atayabilirsiniz buldum. Ancak, global olmayan öğeler için $ routeScope kullanmak bir koku yaratır ve veriler gerçekten kontrolörün $ kapsamına atanmalıdır. Ne yazık ki, yaklaşımınız yenilikçi olsa da ideal değil (sizin için uygun bir şey bulmaya rağmen saygı). Ben sadece bir şekilde veri için bekleyen ve kapsam atama izin veren bir istemci tarafı cevap olması gerektiğine eminim. Arama devam ediyor!
dewd

Birisi için yararlı olması durumunda, yakın zamanda diğer insanların yazdığı ve ngModules web sitesine eklediği modüllere bakarak bazı farklı yaklaşımlar gördüm. Daha fazla zaman aldığımda ya bunlardan birini kullanmaya başlamam gerekecek ya da ne yaptıklarını çözüp eşyalarıma eklemem gerekecek.
2013


1

JSONPServis verilerini eşzamansız olarak yüklemek için kullanabilirsiniz . JSONP isteği ilk sayfa yüklemesi sırasında yapılacak ve sonuçlar uygulamanız başlamadan önce kullanılabilecektir. Bu şekilde, yedekli çözümlerle yönlendirmenizi şişirmek zorunda kalmazsınız.

Html şöyle görünecektir:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script>

function MyService {
  this.getData = function(){
    return   MyService.data;
  }
}
MyService.setData = function(data) {
  MyService.data = data;
}

angular.module('main')
.service('MyService', MyService)

</script>
<script src="/some_data.php?jsonp=MyService.setData"></script>

-1

Başlatmak için ng-init dizinini kullanmanın en kolay yolu.

Sadece init verilerini almak istediğiniz yere ng-init div kapsamını koyun

index.html

<div class="frame" ng-init="init()">
    <div class="bit-1">
      <div class="field p-r">
        <label ng-show="regi_step2.address" class="show-hide c-t-1 ng-hide" style="">Country</label>
        <select class="form-control w-100" ng-model="country" name="country" id="country" ng-options="item.name for item in countries" ng-change="stateChanged()" >
        </select>
        <textarea class="form-control w-100" ng-model="regi_step2.address" placeholder="Address" name="address" id="address" ng-required="true" style=""></textarea>
      </div>
    </div>
  </div>

index.js

$scope.init=function(){
    $http({method:'GET',url:'/countries/countries.json'}).success(function(data){
      alert();
           $scope.countries = data;
    });
  };

NOT: bir yerde birden fazla aynı koda sahip değilseniz bu metodolojiyi kullanabilirsiniz.


NgInit'i dokümanlar uyarınca kullanmanız önerilmez: docs.angularjs.org/api/ng/directive/ngInit
fodma1
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.