Bagaimana cara menjalankan fungsi pengontrol AngularJS pada pemuatan halaman?

359

Saat ini saya memiliki halaman Angular.js yang memungkinkan pencarian dan menampilkan hasil. Pengguna mengklik hasil pencarian, lalu mengklik tombol kembali. Saya ingin hasil pencarian ditampilkan lagi tetapi saya tidak dapat menemukan cara untuk memicu pencarian untuk dieksekusi. Inilah detailnya:

  • Halaman Angular.js saya adalah halaman pencarian, dengan bidang pencarian dan tombol pencarian. Pengguna dapat secara manual mengetik kueri dan menekan tombol dan dan ajax kueri dipecat dan hasilnya ditampilkan. Saya memperbarui URL dengan istilah pencarian. Itu semua bekerja dengan baik.
  • Pengguna mengklik hasil pencarian dan dibawa ke halaman lain - yang berfungsi dengan baik juga.
  • Pengguna mengklik tombol kembali, dan kembali ke halaman pencarian sudut saya, dan URL yang benar ditampilkan, termasuk istilah pencarian. Semua berfungsi dengan baik.
  • Saya telah mengikat nilai bidang pencarian ke istilah pencarian di URL, sehingga mengandung istilah pencarian yang diharapkan. Semua berfungsi dengan baik.

Bagaimana cara mendapatkan fungsi pencarian untuk dieksekusi lagi tanpa pengguna harus menekan "tombol pencarian"? Jika itu jquery maka saya akan menjalankan fungsi dalam fungsi documentready. Saya tidak dapat melihat padanan Angular.js.

Duke Dougal
sumber
yang Anda gunakan $routepProvider? Gunakan untuk terhubung ke layanan di aplikasi Anda yang menyediakan data untuk hasil pencarian. Jangan berpikir secara document.readyistilah seperti dengan jQuery. Sulit banyak membantu tanpa melihat bagaimana Anda telah mencari kabel saat ini
charlietfl

Jawaban:

430

Di satu sisi seperti @ Mark-Rajcok katakan Anda hanya bisa pergi dengan fungsi batin pribadi:

// 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();

Anda juga dapat melihat arahan ng-init . Implementasinya akan sangat mirip:

// 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
};

Tetapi berhati-hatilah karena itu menyiratkan dokumentasi sudut (karena v1.2) untuk TIDAK digunakan ng-inituntuk itu. Namun demikian itu tergantung pada arsitektur aplikasi Anda.

Saya menggunakan ng-initketika saya ingin memberikan nilai dari back-end ke aplikasi sudut:

<div data-ng-controller="myCtrl" data-ng-init="init('%some_backend_value%')"></div>
Dmitry Evseev
sumber
6
@ Duke, tidak bisakah Anda hanya meletakkan konten fungsi init () di bagian bawah controller Anda? Yaitu, mengapa Anda perlu menggunakan ng-init dan memiliki fungsi init ()? Ketika pengguna menekan tombol kembali, saya berasumsi Anda beralih pandangan, maka myCtrlcontroller baru dibuat dan dijalankan.
Mark Rajcok
24
Sementara solusi ini berhasil, saya downvoted karena dokumentasi ng-init menyarankan untuk tidak melakukannya. Secara khusus, "Satu-satunya penggunaan ngInit yang tepat untuk aliasing properti khusus dari ngRepeat, seperti yang terlihat dalam demo di bawah ini. Selain itu, Anda harus menggunakan pengontrol daripada ngInit untuk menginisialisasi nilai pada lingkup."
Jason Capriotti
1
Kontroler instantiated setelah html ada di tempatnya.
Dmitry Evseev
3
Bagaimana jika pengontrol digunakan kembali di halaman lain tetapi Anda hanya ingin memecatnya pada halaman tertentu?
Roberto Linares
3
@RobertoLinares Saya pribadi menemukan arahan untuk menjadi tempat yang lebih baik untuk fungsionalitas yang dapat digunakan kembali. Anda dapat memiliki direktif dengan parameter init: <div smth on-init="doWhatever()">. Tentu saja itu tergantung pada kasus penggunaan tertentu.
Dmitry Evseev
135

Coba ini?

$scope.$on('$viewContentLoaded', function() {
    //call it here
});
prinsip holografik
sumber
5
Terima kasih atas jawabannya tetapi jawaban Dmitry cocok dengan apa yang saya cari. Penelitian lebih lanjut tampaknya merekomendasikan terhadap $ viewContentLoaded
Duke Dougal
7
Kasus penggunaan hanya berbeda. Saya menggunakan metode Markus sepanjang waktu juga.
Prinsip holografik
Untuk kasus penggunaan saya ini adalah solusi yang sempurna. Kami perlu memilih teks secara otomatis untuk mendorong pengguna menyalinnya. Halaman dapat dimuat ulang / dikunjungi kembali berkali-kali, jadi $ viewContentLoaded adalah pencocokan tepat. Terima kasih!
Olga Gnatenko
Mungkinkah ini dilakukan beberapa kali? Saya mendapatkan perilaku yang sepertinya meniru itu ...
MadPhysicist
1
Yang ini tidak bekerja untuk saya tetapi $ scope. $ Watch berfungsi. Apa perbedaan utama?
Burak Tokak
59

Saya tidak pernah bisa $viewContentLoadedbekerja untuk saya, dan ng-initharus benar-benar hanya digunakan dalam ng-repeat(sesuai dengan dokumentasi), dan juga memanggil fungsi langsung di controller dapat menyebabkan kesalahan jika kode bergantung pada elemen yang belum didefinisikan. .

Inilah yang saya lakukan dan ini bekerja untuk saya:

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

Kecuali Anda menggunakan ui-router. Maka itu:

$scope.$on('$stateChangeSuccess', function () {
  // do something
});
adam0101
sumber
1
Kamu mengagumkan, temanku.
taco
Apa yang saya butuhkan. Saya benar-benar mencari ini selama dua hari!
hellojebus
3
$scope.$on('$routeChangeSuccess'memadamkan setiap parameter waktu di url berubah (via $locationmisalnya), dan dengan demikian Anda dapat menggunakan hanya $scope.$on('$locationChangeSuccess'. Jika Anda memerlukan pemicu saat memuat / memuat kembali laman, Anda dapat menggunakan $scope.$watch('$viewContentLoaded'seperti yang disarankan di sini. Itu tidak akan menyala selama perubahan parameter url.
Neurotransmitter
menggunakan AngularJS 1.17.2, di dalam controller $ routeChangeSuccess bekerja dengan luar biasa ... hidup lama adam0101 ...
ArifMustafa
43
angular.element(document).ready(function () {

    // your code here

});
Carlos Trujillo
sumber
4
Pasti jawaban yang diterima, ini cara yang lebih aman untuk melakukannya
Marwen Trabelsi
Ini bagus jika kita tidak bekerja dengan $scopedan bukannya bekerja dengan this.
Akash
Kemana ini harus pergi? Saya memilikinya di template saya dan tidak menyala.
Dave
Bukankah lebih baik menyuntikkan $ dokumen dalam kasus ini? angular.element ($ document). sudah ...
jamie
4
Penjelasan akan dihargai
Hidayt Rahman
32

Solusi Dimitri / Mark tidak berfungsi untuk saya tetapi menggunakan fungsi $ timeout tampaknya berfungsi dengan baik untuk memastikan kode Anda hanya berjalan setelah markup diberikan.

# Your controller, including $timeout

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

$timeout($scope.init)

Semoga ini bisa membantu.

guico
sumber
3
Akhirnya. Ini adalah satu-satunya yang bekerja untuk saya. Terima kasih.
zmirc
1
Ini bekerja. Juga jangan lupa untuk menghapus timeout dengan $ timeout.cancel (timer) di mana Anda memiliki var timer = $ timeout ($ scope.init, milidetik); setelah inisialisasi Anda selesai. Juga, saya tidak berpikir $ scope harus memiliki 'var' def dalam kode Anda di atas
Emmanuel NK
Ini harus menjadi jawaban yang diterima. Itu satu-satunya yang bekerja untuk saya (mencoba semua jawaban di atas). Ia bahkan berfungsi jika Anda sedang menunggu iframe untuk memuat.
hello_fr1end
Ini bekerja ! viewcontentLoaded tidak berfungsi untuk saya
dark knight
28

Anda dapat melakukan ini jika Anda ingin menonton objek DOM viewContentLoaded berubah dan kemudian melakukan sesuatu. menggunakan $ scope. $ on berfungsi juga tetapi berbeda terutama ketika Anda memiliki satu mode halaman pada perutean Anda.

 $scope.$watch('$viewContentLoaded', function(){
    // do something
 });
CodeOverRide
sumber
7
Khususnya, jika Anda menggunakan $ rootScope. $ Tonton alih-alih $ rootScope. $ Di atasnya tidak akan aktif pada perubahan rute, jadi Anda dapat menggunakan logika khusus untuk memuat halaman awal.
csahlman
19

Anda dapat menggunakan objek $ window angular:

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

Alternatif lain jika Anda memiliki pengontrol khusus untuk halaman itu:

(function(){
    //code to run
}());
Chipe
sumber
3

Saat menggunakan $ routeProvider Anda dapat menyelesaikan .state dan mem-bootstrap layanan Anda. Ini artinya, Anda akan memuat Pengontrol dan Tampilan, hanya setelah menyelesaikan Layanan Anda:

rute ui

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

Layanan

function ourBootstrapService() {

 function init(){ 
    // this is what we need
 }
}
Leo Lanese
sumber
3

Jawaban Dmitry Evseev yang ditemukan cukup berguna.

Kasus 1: Menggunakan angularJs saja:
Untuk mengeksekusi metode pada pemuatan halaman, Anda dapat menggunakan ng-initdalam view dan mendeklarasikan metode init di controller, karena mengatakan bahwa penggunaan fungsi yang lebih berat tidak disarankan, seperti pada Documents angular pada ng-init :

Arahan ini dapat disalahgunakan untuk menambahkan jumlah logika yang tidak perlu ke dalam templat Anda. Hanya ada beberapa kegunaan ngInit yang tepat, seperti untuk aliasing properti khusus ngRepeat, seperti yang terlihat dalam demo di bawah ini; dan untuk menyuntikkan data melalui skrip sisi server. Selain beberapa kasus ini, Anda harus menggunakan pengontrol daripada ngInit untuk menginisialisasi nilai pada lingkup.

HTML:

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

Pengendali:

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

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

    doSearch($routeParams.searchKeyword);
})

Peringatan: Jangan gunakan pengontrol ini untuk tampilan lain yang dimaksudkan untuk maksud berbeda karena akan menyebabkan metode pencarian dieksekusi di sana juga.

Kasus 2: Menggunakan Ionic:
Kode di atas akan berfungsi, pastikan cache tampilan dinonaktifkan route.jssebagai:

route.js

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

Semoga ini membantu

Kailas
sumber
1
Ini hanya memiliki satu dan berada di bagian paling bawah, senang saya telah turun, cache: falsemelakukannya untuk saya - terima kasih!
Rani Kheir
3

Saya memiliki masalah yang sama dan hanya solusi ini yang bekerja untuk saya (ini menjalankan fungsi setelah DOM lengkap telah dimuat). Saya menggunakan ini untuk gulir ke jangkar setelah halaman dimuat:

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

                        // Your function that runs after all DOM is loaded

                    });
Ginko Balboa
sumber
2

Anda dapat menyimpan hasil pencarian di layanan umum yang dapat digunakan dari mana saja dan tidak jelas saat menavigasi ke halaman lain, dan kemudian Anda dapat mengatur hasil pencarian dengan data yang disimpan untuk klik tombol kembali

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

Untuk tombol punggung Anda

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

memanggil metode awal di dalam fungsi inisialisasi diri.

(function initController() {

    // do your initialize here

})();
Uditha Prasad
sumber