Properti mengatasi $ routeProvider memungkinkan penundaan perubahan rute hingga data dimuat.
Pertama tentukan rute dengan resolve
atribut seperti ini.
angular.module('phonecat', ['phonecatFilters', 'phonecatServices', 'phonecatDirectives']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/phones', {
templateUrl: 'partials/phone-list.html',
controller: PhoneListCtrl,
resolve: PhoneListCtrl.resolve}).
when('/phones/:phoneId', {
templateUrl: 'partials/phone-detail.html',
controller: PhoneDetailCtrl,
resolve: PhoneDetailCtrl.resolve}).
otherwise({redirectTo: '/phones'});
}]);
perhatikan bahwa resolve
properti didefinisikan pada rute.
function PhoneListCtrl($scope, phones) {
$scope.phones = phones;
$scope.orderProp = 'age';
}
PhoneListCtrl.resolve = {
phones: function(Phone, $q) {
// see: https://groups.google.com/forum/?fromgroups=#!topic/angular/DGf7yyD4Oc4
var deferred = $q.defer();
Phone.query(function(successData) {
deferred.resolve(successData);
}, function(errorData) {
deferred.reject(); // you could optionally pass error data here
});
return deferred.promise;
},
delay: function($q, $defer) {
var delay = $q.defer();
$defer(delay.resolve, 1000);
return delay.promise;
}
}
Perhatikan bahwa definisi pengontrol berisi objek penyelesaian yang menyatakan hal-hal yang harus tersedia untuk konstruktor pengontrol. Di sini phones
disuntikkan ke controller dan didefinisikan di resolve
properti.
The resolve.phones
Fungsi bertanggung jawab untuk mengembalikan janji. Semua janji dikumpulkan dan perubahan rute ditunda hingga semua janji terselesaikan.
Demo kerja: http://mhevery.github.com/angular-phonecat/app/#/phones
Sumber: https://github.com/mhevery/angular-phonecat/commit/ba33d3ec2d01b70eb5d3d531619bf90153496831
angular.controller()
definisi tipe controller? Dalam$routeProvider
hal ini, saya pikir Anda harus menggunakan nama string pengontrol.angular.controller()
, Anda dapat menetapkan hasil fungsi ini ke variabel (var MyCtrl = angular.controller(...)
) dan kemudian bekerja dengan itu lebih lanjut (MyCtrl.loadData = function(){..}
). Lihat video eggheadBerikut adalah contoh kerja minimal yang berfungsi untuk Angular 1.0.2
Templat:
JavaScript:
http://jsfiddle.net/dTJ9N/3/
Versi efisien:
Karena $ http () sudah mengembalikan janji (alias ditangguhkan), kami sebenarnya tidak perlu membuat sendiri. Jadi kita bisa menyederhanakan MyCtrl. memutuskan untuk:
Hasil $ http () berisi data , status , header dan objek konfigurasi , jadi kita perlu mengubah tubuh MyCtrl menjadi:
http://jsfiddle.net/dTJ9N/5/
sumber
Unknown provider: datasetsProvider <- datasets
function($http) { return $http({method: 'GET', url: '/someUrl'}) .then( function(data){ return data;}, function(reason){return 'error value';} ); }
Saya melihat beberapa orang bertanya bagaimana melakukan ini menggunakan metode angular.controller dengan injeksi dependensi ramah minification. Karena saya baru mendapatkan pekerjaan ini, saya merasa berkewajiban untuk kembali dan membantu. Inilah solusi saya (diadopsi dari pertanyaan awal dan jawaban Misko):
Karena kode ini berasal dari pertanyaan / jawaban yang paling populer, kode ini tidak diuji, tetapi harus mengirim Anda ke arah yang benar jika Anda sudah mengerti cara membuat kode sudut ramah minifikasi. Satu bagian yang tidak saya perlukan adalah kode injeksi "Telepon" ke fungsi tekad untuk 'ponsel', saya juga tidak menggunakan objek 'penundaan' sama sekali.
Saya juga merekomendasikan video youtube ini http://www.youtube.com/watch?v=P6KITGRQujQ&list=UUKW92i7iQFuNILqQOUOCrFw&index=4&feature=plcp , yang membantu saya sedikit
Jika Anda tertarik, saya memutuskan untuk juga menempelkan kode saya sendiri (Ditulis dalam coffeescript) sehingga Anda dapat melihat bagaimana saya membuatnya berfungsi.
FYI, sebelumnya saya menggunakan pengontrol generik yang membantu saya melakukan CRUD pada beberapa model:
sumber
resolve
fungsi di controller, dalam versi terbaru Angular? Jadi itu harus dinyatakan tepat di konfigurasi seperti di sini?$defer
layanan yang tidak ditentukan , harap perhatikan bahwa dalam versi 1.5.7 dari AngularJS, Anda ingin menggunakannya$timeout
sebagai gantinya.Komit ini , yang merupakan bagian dari versi 1.1.5 dan di atasnya, memperlihatkan
$promise
objek$resource
. Versi ngResource termasuk komit ini memungkinkan penyelesaian sumber daya seperti ini:$ routeProvider
pengontrol
sumber
GET '/api/1/apps/:appId'
->App.get({id: $routeParams.appId}).$promise();
Saya tidak bisa menggunakan seperti ini$route
ke tekad dan penggunaan Anda$route.current.params
. Hati-hati,$routeParams
masih menunjuk ke rute lama.Cuplikan ini ramah injeksi ketergantungan (saya bahkan menggunakannya dalam kombinasi ngmin dan uglify ) dan ini adalah penggerak domain yang lebih elegan solusi berbasis .
Contoh di bawah ini mendaftarkan sumber daya Phone dan PhoneRout yang konstan , yang berisi semua informasi perutean Anda untuk domain (telepon) itu. Sesuatu yang saya tidak suka dalam jawaban yang diberikan adalah lokasi dari logika tekad - modul utama tidak boleh tahu apa-apa atau merasa terganggu tentang cara argumen sumber daya diberikan ke controller. Dengan cara ini, logika tetap berada di domain yang sama.
Catatan: jika Anda menggunakan ngmin (dan jika tidak: Anda seharusnya), Anda hanya perlu menulis fungsi ketetapan dengan konvensi array DI.
Bagian selanjutnya adalah menyuntikkan data perutean ketika modul berada dalam status configure dan menerapkannya ke $ routeProvider .
Menguji konfigurasi rute dengan pengaturan ini juga cukup mudah:
Anda dapat melihatnya dalam kemuliaan penuh dalam percobaan terbaru saya (yang akan datang) . Walaupun metode ini bekerja dengan baik untuk saya, saya benar-benar bertanya-tanya mengapa $ injector tidak menunda pembangunan apa pun ketika mendeteksi injeksi apa pun yang merupakan objek janji ; itu akan membuat segalanya jadi lebih mudah.
Sunting: digunakan Angular v1.2 (rc2)
sumber
I really wonder why the $injector isn't delaying construction of anything when it detects injection of anything that is a promise object
Saya menduga mereka menghilangkan fungsi ini karena mungkin mendorong pola desain yang berdampak negatif terhadap respons aplikasi. Aplikasi ideal dalam pikiran mereka adalah aplikasi yang benar-benar tidak sinkron, jadi penyelesaian harus menjadi kasus tepi.Menunda menunjukkan rute pasti akan mengarah ke kusut asinkron ... mengapa tidak hanya melacak status pemuatan entitas utama Anda dan menggunakannya dalam tampilan. Misalnya di controller Anda, Anda mungkin menggunakan callback sukses dan kesalahan pada ngResource:
Maka dalam tampilan Anda bisa melakukan apa saja:
sumber
Saya bekerja dari kode Misko di atas dan inilah yang telah saya lakukan dengannya. Ini adalah solusi yang lebih terkini karena
$defer
telah diubah menjadi$timeout
.$timeout
Namun, penggantian akan menunggu periode waktu habis (dalam kode Misko, 1 detik), lalu kembalikan data dengan harapan waktu diselesaikan. Dengan cara ini, ia kembali secepatnya.sumber
Menggunakan AngularJS 1.1.5
Memperbarui fungsi 'ponsel' dalam jawaban Justen menggunakan sintaks AngularJS 1.1.5 .
Asli:
Diperbarui:
Jauh lebih singkat berkat tim dan kontributor Angular. :)
Ini juga jawaban Maximilian Hoffmann. Tampaknya komit berhasil masuk ke 1.1.5.
sumber
$promise
di dokumen . Mungkin sudah dikeluarkan pada v2.0 +.Anda dapat menggunakan properti penyelesaian $ routeProvider untuk menunda perubahan rute sampai data dimuat.
Perhatikan bahwa
resolve
properti ditentukan pada rute.EntitiesCtrlResolve
danEntityCtrlResolve
adalah konstan benda didefinisikan dalam file yang samaEntitiesCtrl
danEntityCtrl
pengendali.sumber
Saya menyukai ide darkporter karena akan mudah bagi tim dev yang baru di AngularJS untuk memahami dan bekerja langsung.
Saya membuat adaptasi ini yang menggunakan 2 divs, satu untuk loader bar dan satu lagi untuk konten aktual yang ditampilkan setelah data dimuat. Penanganan kesalahan akan dilakukan di tempat lain.
Tambahkan bendera 'siap' ke $ scope:
Dalam tampilan html:
Lihat juga: Boostrap progress bar docs
sumber
Saya suka jawaban di atas dan belajar banyak dari mereka tetapi ada sesuatu yang hilang dalam sebagian besar jawaban di atas.
Saya terjebak dalam skenario serupa di mana saya menyelesaikan url dengan beberapa data yang diambil pada permintaan pertama dari server. Masalah yang saya hadapi adalah bagaimana jika janji itu
rejected
.Saya menggunakan penyedia kustom yang digunakan untuk mengembalikan
Promise
yang diselesaikan olehresolve
dari$routeProvider
pada saat fase config.Yang ingin saya tekankan di sini adalah konsep
when
melakukan sesuatu seperti ini.Ia melihat url di bar url dan kemudian masing-masing
when
blok di disebut controller dan view sejauh ini sangat bagus.Katakanlah saya telah mengikuti kode fase konfigurasi.
Pada url root di browser blok pertama dijalankan dipanggil sebaliknya
otherwise
dipanggil.Mari kita bayangkan sebuah skenario yang saya tekan rootUrl di
AuthServicePrivider.auth()
fungsi address bar dipanggil.Katakanlah Janji dikembalikan dalam keadaan menolak lalu bagaimana ???
Tidak ada yang diberikan sama sekali.
Otherwise
blok tidak akan dieksekusi karena untuk url apa pun yang tidak didefinisikan dalam blok konfigurasi dan tidak diketahui oleh fase konfigurasi angularJs.Kami harus menangani acara yang dipecat ketika janji ini tidak terselesaikan. Pada kegagalan
$routeChangeErorr
dipecat$rootScope
.Itu dapat ditangkap seperti yang ditunjukkan pada kode di bawah ini.
IMO Ini umumnya ide yang baik untuk meletakkan kode pelacakan acara dalam menjalankan blok aplikasi. Kode ini berjalan tepat setelah fase konfigurasi aplikasi.
Dengan cara ini kita dapat menangani kegagalan janji pada saat tahap konfigurasi.
sumber
Saya memiliki antarmuka panel geser multi-level yang kompleks, dengan lapisan layar yang dinonaktifkan. Membuat arahan pada menonaktifkan lapisan layar yang akan membuat acara klik untuk mengeksekusi keadaan seperti
menghasilkan efek menjentikkan. history.back () bukannya berfungsi dengan baik, namun itu tidak selalu kembali dalam sejarah dalam kasus saya. SO yang saya temukan adalah bahwa jika saya hanya membuat atribut href pada layar menonaktifkan saya alih-alih state.go, bekerja seperti pesona.
Arahan 'kembali'
app.js Saya baru saja menyimpan status sebelumnya
sumber
Salah satu solusi yang mungkin adalah dengan menggunakan arahan ng-jubah dengan elemen di mana kita menggunakan model misalnya
Saya pikir ini membutuhkan sedikit usaha.
sumber