Sayfa yüklemesinde AngularJS denetleyici işlevi nasıl çalıştırılır?


361

Şu anda aramaya izin veren ve sonuçları görüntüleyen bir Angular.js sayfam var. Kullanıcı bir arama sonucunu, ardından geri düğmesini tıklar. Arama sonuçlarının tekrar görüntülenmesini istiyorum, ancak aramanın yürütülmesi için nasıl tetikleneceğini öğrenemiyorum. İşte detay:

  • Angular.js sayfam, arama alanı ve arama düğmesi bulunan bir arama sayfasıdır. Kullanıcı elle bir sorgu yazıp bir düğmeye basabilir ve ajax sorgusu tetiklenir ve sonuçlar görüntülenir. URL'yi arama terimiyle güncelliyoruz. Hepsi iyi çalışıyor.
  • Kullanıcı aramanın sonucunu tıklar ve farklı bir sayfaya yönlendirilir - bu da işe yarar.
  • Kullanıcı geri düğmesini tıklar ve açısal arama sayfama geri döner ve arama terimi de dahil olmak üzere doğru URL görüntülenir. Tüm iyi çalışıyor.
  • Arama alanı değerini URL'deki arama terimine bağladım, bu nedenle beklenen arama terimini içeriyor. Tüm iyi çalışıyor.

Kullanıcının "arama düğmesine" basmak zorunda kalmadan arama işlevinin yeniden yürütülmesini nasıl sağlayabilirim? Jquery olsaydı ben zaten zaten fonksiyonunda bir işlevi yürütmek. Angular.js eşdeğerini göremiyorum.


kullanıyor $routepProvidermusun Arama sonuçları için veri sağlayan uygulamanızdaki servise bağlanmak için kullanın. document.readyJQuery gibi düşünmeyin . Şu anda nasıl arama yaptığını görmeden çok yardım etmek zor
charlietfl

Yanıtlar:


430

Bir yandan @ Mark-Rajcok'un dediği gibi, özel iç işlevden kurtulabilirsiniz:

// at the bottom of your controller
var init = function () {
   // check if there is query in url
   // and fire search in case its value is not empty
};
// and fire it after definition
init();

Ayrıca ng-init yönergesine de bakabilirsiniz . Uygulama şöyle olacaktır:

// register controller in html
<div data-ng-controller="myCtrl" data-ng-init="init()"></div>

// in controller
$scope.init = function () {
    // check if there is query in url
    // and fire search in case its value is not empty
};

Ancak, açısal belgelerin (v1.2'den beri) bunun için KULLANMAMASI gerektiği gibi dikkat ng-initedin. Ancak imo, uygulamanızın mimarisine bağlıdır.

ng-initArka uçtan bir değeri açısal uygulamaya geçirmek istediğimde kullandım :

<div data-ng-controller="myCtrl" data-ng-init="init('%some_backend_value%')"></div>

6
@ Duke, init () işlevinin içeriğini kumandanızın altına koyamaz mısınız? Yani, neden ng-init kullanmanız ve init () fonksiyonuna sahip olmanız gerekiyor? Kullanıcı geri düğmesine bastığında, görünümler arasında geçiş yaptığınızı varsayarız, böylece yeni bir myCtrldenetleyici oluşturulur ve yürütülür.
Mark Rajcok

24
Bu çözüm çalışırken, ng-init belgeleri buna karşı tavsiyede bulunduğundan aşağı indirdim. Özellikle, "Aşağıdaki demoda görüldüğü gibi ngRepeat'in özel özelliklerini yumuşatmak için ngInit'in tek uygun kullanımı. Bu durumda, kapsamdaki değerleri başlatmak için ngInit yerine denetleyiciler kullanmalısınız."
Jason Capriotti

1
Html yerinde olduğunda denetleyici başlatılır.
Dmitry Evseev

3
Denetleyici diğer sayfalarda yeniden kullanılıyor, ancak yalnızca belirli bir sayfada tetiklenmek istiyorsanız ne olur?
Roberto Linares

3
@RobertoLinares Kişisel olarak yeniden kullanılabilir işlevsellik için daha iyi bir yer olması için yönergeler buluyorum. Bir init parametre ile bir yönerge sahip olabilir: <div smth on-init="doWhatever()">. Tabii ki bu belirli bir kullanım durumuna bağlıdır.
Dmitry Evseev

135

Bunu dene?

$scope.$on('$viewContentLoaded', function() {
    //call it here
});

5
Cevabınız için teşekkürler ama Dmitry'nin cevabı aradığım şeyle tam olarak eşleşti. $ ViewContentLoaded
Duke Dougal

7
Kullanım durumları sadece farklıdır. Mark'ın yöntemini de her zaman kullanıyorum.
holografik prensip

Benim kullanım durumum için bu mükemmel bir çözümdü. Kullanıcıyı kopyalamaya teşvik etmek için metni otomatik olarak seçmemiz gerekiyordu. Sayfa birçok kez yeniden yüklenebilir / yeniden ziyaret edilebilir, bu nedenle $ viewContentLoaded tam bir eşleşmeydi. Teşekkürler!
Olga Gnatenko

Bunun birkaç kez yapılması mümkün mü? Bunu taklit eden bir davranış alıyorum ...
MadPhysicist

1
Bu benim için işe yaramadı ama $ scope. $ Watch çalıştı. Temel fark nedir?
Burak Tokak

59

Asla $viewContentLoadedbenim için çalışmaya başlayamadım ve ng-initgerçekten sadece ng-repeat(belgelere göre) kullanılmalıdır ve ayrıca bir işlev doğrudan denetleyicide çağırmak kod henüz tanımlanmamış bir öğeye dayanıyorsa hatalara neden olabilir .

Yaptığım şey bu ve benim için çalışıyor:

$scope.$on('$routeChangeSuccess', function () {
  // do something
});

Eğer kullanmadığınız sürece ui-router. Sonra:

$scope.$on('$stateChangeSuccess', function () {
  // do something
});

1
Harikasın dostum.
taco

Tam olarak ihtiyacım olan şey. Kelimenin tam anlamıyla bu iki gün arıyordu!
hellojebus

3
$scope.$on('$routeChangeSuccess'url'deki parametreler her değiştiğinde tetiklenir ( $locationörneğin) ve böylece kullanabilirsiniz $scope.$on('$locationChangeSuccess'. Sayfa yükleme / yeniden yükleme işleminde tetikleyiciye ihtiyacınız varsa, $scope.$watch('$viewContentLoaded'burada önerildiği gibi kullanabilirsiniz . URL parametreleri değişiklikleri sırasında tetiklenmez.
Nörotransmitter

AngularJS 1.17.2 kullanarak, denetleyici $ routeChangeSuccess içinde inanılmaz çalıştı ... çok yaşa adam0101 ...
ArifMustafa

43
angular.element(document).ready(function () {

    // your code here

});

4
Kabul edilen cevap olmalı, bunu yapmak için daha güvenli bir yol
Marwen Trabelsi

$scopeBirlikte çalışmadığımız ve bunun yerine çalıştığımız takdirde bu iyidir this.
Akash,

Bunun nereye gitmesi gerekiyor? Benim şablonumda var ve ateş etmiyor.
Dave

Bu durumda $ belge enjekte etmek iyi olmaz mıydı? angular.element ($ document) .ready ...
jamie

5
Açıklama takdir edilecektir
Hidayt Rahman

32

Dimitri'nin / Mark'ın çözümü benim için işe yaramadı ama $ timeout işlevini kullanmak, kodunuzun yalnızca biçimlendirme oluşturulduktan sonra çalışmasını sağlamak için iyi çalışıyor gibi görünüyor.

# Your controller, including $timeout

var $scope.init = function(){
 //your code
}

$timeout($scope.init)

Umarım yardımcı olur.


3
En sonunda. Benim için çalışan tek kişi bu. Teşekkürler.
zmirc

1
Bu çalışıyor. Ayrıca, zamanlayıcı = $ timeout ($ scope.init, milisaniye) bulunan $ timeout.cancel (timer) ile zaman aşımını temizlemeyi unutmayın; başlatma işleminiz tamamlandıktan sonra. Ayrıca, $ kapsamı yukarıdaki kodunuzda bir 'var' def olması gerektiğini sanmıyorum
Emmanuel NK

Bu kabul edilen cevap olmalı. Benim için çalışan tek kişi buydu (yukarıdaki tüm cevapları denedim). Bir iframe'in yüklenmesi için bekliyorsanız bile çalışır.
hello_fr1end

28

ViewContentLoaded DOM nesnesini değiştirmek ve sonra bir şeyler yapmak için izlemek istiyorsanız bunu yapabilirsiniz. $ scope. $ on kullanarak, özellikle yönlendirmenizde bir sayfa modu olduğunda çok farklı çalışır.

 $scope.$watch('$viewContentLoaded', function(){
    // do something
 });

7
Özellikle, $ rootScope. $ Yerine $ rootScope. $ Watch kullanıyorsanız, rota değişikliklerinde tetiklenmeyeceğinden, ilk sayfa yüklemesine özgü mantığı kullanabilirsiniz.
csahlman

19

Açısal'ın $ window nesnesini kullanabilirsiniz:

$window.onload = function(e) {
  //your magic here
}


3

Bu sayfaya özgü bir denetleyiciniz varsa başka bir alternatif:

(function(){
    //code to run
}());

3

$ RouteProvider kullanırken .state üzerinde çözebilir ve hizmetinizi bootstrap edebilirsiniz. Bu, yalnızca Hizmetinizi çözdükten sonra Denetleyici ve Görünüm'ü yükleyeceğiniz anlamına gelir:

ui-rotalar

 .state('nn', {
        url: "/nn",
        templateUrl: "views/home/n.html",
        controller: 'nnCtrl',
        resolve: {
          initialised: function (ourBootstrapService, $q) {

            var deferred = $q.defer();

            ourBootstrapService.init().then(function(initialised) {
              deferred.resolve(initialised);
            });
            return deferred.promise;
          }
        }
      })

Hizmet

function ourBootstrapService() {

 function init(){ 
    // this is what we need
 }
}

3

Dmitry Evseev cevap oldukça yararlı bulundu.

Durum 1: Tek başına angularjs kullanma:
sayfa yüklemesinde bir yöntemi uygulamak için kullanabilirsiniz ng-initağır fonksiyonun kullanımının gereğince, tavsiye edilmez dedi sahip denetleyici görünümü ve beyan init yönteminde açısal Dokümanlar ng-init üzerinde :

Bu yönerge, şablonlarınıza gereksiz miktarlarda mantık eklemek için kötüye kullanılabilir. Aşağıdaki demoda görüldüğü gibi ngRepeat'in özel özelliklerini yumuşatmak gibi ngInit'in yalnızca birkaç uygun kullanımı vardır; ve sunucu tarafı komut dosyası aracılığıyla veri enjekte etmek için. Bu birkaç durumun yanı sıra, kapsamdaki değerleri başlatmak için ngInit yerine denetleyiciler kullanmalısınız.

HTML:

<div ng-controller="searchController()">
    <!-- renaming view code here, including the search box and the buttons -->
</div>

Denetleyici:

app.controller('SearchCtrl', function(){

    var doSearch = function(keyword){
        //Search code here
    }

    doSearch($routeParams.searchKeyword);
})

Uyarı: Bu denetleyiciyi, arama yönteminin burada da yürütülmesine neden olacağından farklı bir amaç anlamına gelen başka bir görünüm için kullanmayın.

Durum 2: İyonik kullanımı:
Yukarıdaki kod işe yarayacak, sadece görünüm önbelleğinin aşağıdaki gibi devre dışı bırakıldığından emin olun route.js:

route.js

.state('app', {
    url           : '/search',
    cache         : false, //disable caching of the view here
    templateUrl   : 'templates/search.html'   ,
    controller    : 'SearchCtrl'
  })

Bu yardımcı olur umarım


1
Bu sadece bir tane vardı ve en altta oldu, ben tüm yol aşağı gitti sevindim, benim için cache: falseyaptım - teşekkürler!
Rani Kheir

3

Aynı sorunu yaşadım ve sadece bu çözüm benim için çalıştı (tam bir DOM yüklendikten sonra bir işlevi çalıştırır). Bu sayfa yüklendikten sonra tutturmak için kaydırma için kullanın:

angular.element(window.document.body).ready(function () {

                        // Your function that runs after all DOM is loaded

                    });

2

Arama sonuçlarını herhangi bir yerden kullanabileceğiniz ve başka bir sayfaya gittiğinizde temizlenmeyen ortak bir hizmete kaydedebilir ve ardından geri arama düğmesi için arama sonuçlarını kaydedilmiş verilerle ayarlayabilirsiniz

function search(searchTerm) {
    // retrieve the data here;
    RetrievedData = CallService();
    CommonFunctionalityService.saveSerachResults(RetrievedData);
} 

Backbutton'ınız için

function Backbutton() {
    RetrievedData = CommonFunctionalityService.retrieveResults();
}

0

kendini başlatma işlevi içindeki başlangıç ​​yöntemlerini çağırır.

(function initController() {

    // do your initialize here

})();
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.