Saya ingin menambahkan beberapa fungsi utilitas ke aplikasi AngularJS saya. Sebagai contoh:
$scope.isNotString = function (str) {
return (typeof str !== "string");
}
Apakah cara terbaik untuk melakukan ini untuk menambahkannya sebagai layanan? Dari apa yang telah saya baca saya dapat melakukan ini tetapi kemudian saya ingin menggunakannya di halaman HTML saya jadi apakah masih mungkin jika mereka berada dalam layanan? Misalnya saya dapat menggunakan yang berikut ini:
<button data-ng-click="doSomething()"
data-ng-disabled="isNotString(abc)">Do Something
</button>
Dapatkah seseorang memberi saya contoh bagaimana saya bisa menambahkan ini. Haruskah saya membuat layanan atau ada cara lain untuk melakukannya. Paling penting saya ingin fungsi utilitas ini dalam file dan tidak dikombinasikan dengan bagian lain dari pengaturan utama.
Saya mengerti ada beberapa solusi tetapi tidak satupun yang jelas.
Solusi 1 - Diusulkan oleh Urban
$scope.doSomething = ServiceName.functionName;
Masalahnya di sini adalah saya memiliki 20 fungsi dan sepuluh pengendali. Jika saya melakukan ini, itu berarti menambahkan banyak kode ke setiap kontroler.
Solusi 2 - Diusulkan oleh saya
var factory = {
Setup: function ($scope) {
$scope.isNotString = function (str) {
return (typeof str !== "string");
}
Kerugian dari ini adalah bahwa pada awal setiap controller saya akan memiliki satu atau lebih dari panggilan Setup untuk setiap layanan yang melewati $ scope.
Solusi 3 - Diusulkan oleh Urban
Solusi yang diajukan oleh kota untuk menciptakan layanan generik terlihat bagus. Inilah pengaturan utama saya:
var app = angular
.module('app', ['ngAnimate', 'ui.router', 'admin', 'home', 'questions', 'ngResource', 'LocalStorageModule'])
.config(['$locationProvider', '$sceProvider', '$stateProvider',
function ($locationProvider, $sceProvider, $stateProvider) {
$sceProvider.enabled(false);
$locationProvider.html5Mode(true);
Haruskah saya menambahkan layanan umum ke ini dan bagaimana saya bisa melakukannya?
Jawaban:
EDIT 7/1/15:
Saya menulis jawaban ini cukup lama dan belum banyak menjaga sudut dengan sudut pandang untuk sementara waktu, tetapi sepertinya jawaban ini masih relatif populer, jadi saya ingin menunjukkan bahwa beberapa titik @nicolas membuat di bawah ini bagus. Pertama, menyuntikkan $ rootScope dan melampirkan pembantu di sana akan membuat Anda tidak perlu menambahkannya untuk setiap pengontrol. Juga - Saya setuju bahwa jika apa yang Anda tambahkan harus dianggap sebagai layanan ATAU filter, mereka harus diadopsi ke dalam kode dengan cara itu.
Juga, pada versi 1.4.2 saat ini, Angular mengekspos API "Penyedia", yang diizinkan untuk disuntikkan ke blok konfigurasi. Lihat sumber daya ini untuk lebih banyak:
https://docs.angularjs.org/guide/module#module-loading-dependencies
Injeksi ketergantungan nilai AngularJS di dalam module.config
Saya tidak berpikir saya akan memperbarui blok kode aktual di bawah ini, karena saya tidak benar-benar aktif menggunakan Angular hari ini dan saya tidak benar-benar ingin membahayakan jawaban baru tanpa merasa nyaman bahwa itu benar-benar sesuai dengan yang terbaik baru praktik. Jika orang lain merasa sanggup melakukannya, tentu saja lakukanlah.
EDIT 2/3/14:
Setelah memikirkan hal ini dan membaca beberapa jawaban lain, saya sebenarnya berpikir saya lebih suka variasi metode yang dibawakan oleh @Brent Washburne dan @Amogh Talpallikar. Terutama jika Anda mencari utilitas seperti isNotString () atau serupa. Salah satu keuntungan yang jelas di sini adalah Anda dapat menggunakannya kembali di luar kode sudut Anda dan Anda dapat menggunakannya di dalam fungsi konfigurasi Anda (yang tidak dapat Anda lakukan dengan layanan).
Yang sedang berkata, jika Anda mencari cara umum untuk menggunakan kembali apa yang seharusnya menjadi layanan, jawaban lama saya pikir masih bagus.
Apa yang akan saya lakukan sekarang adalah:
app.js:
controller.js:
Kemudian di parsial Anda, Anda dapat menggunakan:
Jawaban lama di bawah:
Mungkin yang terbaik untuk memasukkan mereka sebagai layanan. Jika Anda akan menggunakannya kembali di banyak pengontrol, termasuk mereka sebagai layanan akan membuat Anda tidak perlu mengulangi kode.
Jika Anda ingin menggunakan fungsi layanan di sebagian html Anda, maka Anda harus menambahkannya ke lingkup pengontrol itu:
$scope.doSomething = ServiceName.functionName;
Kemudian di parsial Anda, Anda dapat menggunakan:
Inilah cara Anda dapat menjaga ini semua terorganisir dan bebas dari kerumitan terlalu banyak:
Pisahkan pengontrol, layanan, dan kode perutean / konfigurasi menjadi tiga file: controllers.js, services.js, dan app.js. Modul lapisan atas adalah "app", yang memiliki app.controllers dan app.services sebagai dependensi. Kemudian app.controllers dan app.services dapat dideklarasikan sebagai modul dalam file mereka sendiri. Struktur organisasi ini diambil dari Benih Angular :
app.js:
layanan.js:
controller.js:
Kemudian di parsial Anda, Anda dapat menggunakan:
Dengan begitu Anda hanya menambahkan satu baris kode ke setiap pengontrol dan dapat mengakses fungsi layanan mana pun di mana ruang lingkup itu dapat diakses.
sumber
Datang di utas lama ini saya ingin menekankan itu
1 °) fungsi utilitas dapat (harus?) Ditambahkan ke rootscope melalui module.run. Tidak perlu untuk instanciate pengendali level root spesifik untuk tujuan ini.
2 °) Jika Anda mengatur kode Anda ke dalam modul yang terpisah, Anda harus menggunakan layanan sudut atau pabrik dan kemudian menyuntikkannya ke dalam fungsi yang diteruskan ke run block, sebagai berikut:
3 °) Pemahaman saya adalah bahwa dalam pandangan, untuk sebagian besar kasus Anda memerlukan fungsi pembantu ini untuk menerapkan semacam pemformatan ke string yang Anda tampilkan. Yang Anda butuhkan dalam kasus terakhir ini adalah menggunakan filter sudut
Dan jika Anda telah menyusun beberapa metode pembantu tingkat rendah ke layanan sudut atau pabrik, cukup masukkan dalam konstruktor filter Anda:
Dan menurut Anda:
sumber
run
waktu. Bagaimana dengan waktu konfigurasi? Bukankah kita membutuhkan utilitas di luar sana?Apakah saya mengerti dengan benar bahwa Anda hanya ingin mendefinisikan beberapa metode utilitas dan membuatnya tersedia dalam templat?
Anda tidak harus menambahkannya ke setiap pengontrol. Cukup tentukan satu pengontrol tunggal untuk semua metode utilitas dan pasang pengontrol itu ke <html> atau <body> (menggunakan arahan ngController). Kontroler lain yang Anda lampirkan di mana saja di bawah <html> (artinya di mana saja, titik) atau <body> (di mana saja kecuali <head>) akan mewarisi $ lingkup itu dan akan memiliki akses ke metode-metode itu.
sumber
<div class="main-container" ng-controller="UtilController as util">
kemudian dalam setiap tampilan interior:<button ng-click="util.isNotString(abc)">
Cara termudah untuk menambahkan fungsi utilitas adalah membiarkannya di tingkat global:
Kemudian, cara paling sederhana untuk menambahkan fungsi utilitas (ke pengontrol) adalah dengan menetapkannya
$scope
, seperti ini:Maka Anda dapat menyebutnya seperti ini:
atau seperti ini:
EDIT:
Pertanyaan aslinya adalah apakah cara terbaik untuk menambahkan fungsi utilitas adalah melalui layanan. Saya bilang tidak, jika fungsinya cukup sederhana (seperti
isNotString()
contoh yang diberikan oleh OP).Manfaat dari penulisan layanan adalah untuk menggantinya dengan layanan lain (melalui injeksi) untuk tujuan pengujian. Secara ekstrim, apakah Anda perlu menyuntikkan setiap fungsi utilitas tunggal ke dalam pengontrol Anda?
Dokumentasi mengatakan untuk mendefinisikan perilaku di controller (seperti
$scope.double
): http://docs.angularjs.org/guide/controllersumber
Ini adalah metode sederhana, ringkas dan mudah dipahami yang saya gunakan.
Pertama, tambahkan layanan di js Anda.
Kemudian, di controller Anda, menyuntikkan objek pembantu Anda dan menggunakan fungsi apa pun yang tersedia dengan sesuatu seperti berikut:
sumber
Anda juga dapat menggunakan layanan konstan. Menentukan fungsi di luar panggilan konstan memungkinkannya menjadi rekursif juga.
sumber
Mengapa tidak menggunakan pewaris pengontrol, semua metode / properti yang didefinisikan dalam lingkup HeaderCtrl dapat diakses di pengontrol di dalam tampilan-ng. $ scope.servHelper dapat diakses di semua pengontrol Anda.
sumber