Cara menggunakan does javascript use pascalcase?

Tujuan dari panduan ini adalah memberikan standar gaya dan cara-cara terbaik menulis kode untuk sebuah aplikasi AngularJS. Cara-cara ini dikumpulkan dari:

  1. Kode sumber AngularJS
  2. Kode-kode atau artikel yang pernah saya baca
  3. Pengalaman saya sendiri

Catatan 1: Panduan ini masih berupa konsep, tujuan utamanya adalah agar dikendalikan oleh komunitas, jadi menyumbangkan waktu anda untuk proyek ini akan sangat dihargai seluruh komunitas.

Catatan 2: Sebelum mengikuti panduan ini, pastikan bahwa panduan ini versi yang terbaru atau sama dengan versi dalam bahasa inggris (bisa anda cek dari waktu commit).

Dalam panduan ini, anda tidak akan menemukan panduan umum untuk menulis kode javascript. Seperti yang bisa anda temukan di:

  1. Panduan menulis kode javascript milik Google
  2. Panduan menulis kode javascript milik Mozilla
  3. Panduan menulis kode javascript milik Douglas
  4. Panduan menulis kode javascript milik Airbnb

Tapi setidaknya kami merekomendasikan anda untuk mengikuti Panduan menulis kode javascript milik Google.

Di halaman GitHub milik AngularJS ada sebuah wiki yang bagus seputar topik ini, kontribusi dari ProLoser, anda bisa melihatnya di sini.

Daftar isi
Umum

Struktur Direktori

Karena sebuah aplikasi bisa mempunyai banyak komponen, sangat baik untuk membuatnya terstruktur seperti struktur direktori. Ada 2 struktur yang biasa digunakan:

Struktur 1: Membagi menjadi 2 divisi, divisi atas disusun berdasarkan komponen, divisi bawah berdasarkan fungsionalitas.

Dengan cara ini, struktur akan terlihat seperti ini:

.
├── app
│   ├── app.js
│   ├── controllers
│   │   ├── home
│   │   │   ├── FirstCtrl.js
│   │   │   └── SecondCtrl.js
│   │   └── about
│   │       └── ThirdCtrl.js
│   ├── directives
│   │   ├── home
│   │   │   └── directive1.js
│   │   └── about
│   │       ├── directive2.js
│   │       └── directive3.js
│   ├── filters
│   │   ├── home
│   │   └── about
│   └── services
│       ├── CommonService.js
│       ├── cache
│       │   ├── Cache1.js
│       │   └── Cache2.js
│       └── models
│           ├── Model1.js
│           └── Model2.js
├── partials
├── lib
└── test

Struktur 2: Membagi menjadi 2 divisi, divisi atas disusun berdasarkan fungsionalitas, divisi bawah berdasarkan komponen.

Dengan cara ini, struktur akan terlihat seperti ini:

.
├── app
│   ├── app.js
│   ├── common
│   │   ├── controllers
│   │   ├── directives
│   │   ├── filters
│   │   └── services
│   ├── home
│   │   ├── controllers
│   │   │   ├── FirstCtrl.js
│   │   │   └── SecondCtrl.js
│   │   ├── directives
│   │   │   └── directive1.js
│   │   ├── filters
│   │   │   ├── filter1.js
│   │   │   └── filter2.js
│   │   └── services
│   │       ├── service1.js
│   │       └── service2.js
│   └── about
│       ├── controllers
│       │   └── ThirdCtrl.js
│       ├── directives
│       │   ├── directive2.js
│       │   └── directive3.js
│       ├── filters
│       │   └── filter3.js
│       └── services
│           └── service3.js
├── partials
├── lib
└── test

Struktur tambahan: Ketika membuat directives, akan sangat memudahkan apabila anda menempatkan semua file yang berhubungan (seperti: templates, CSS/SASS) di dalam direktori yang sama. Jika anda mengikuti cara ini, anda harus konsisten.

app
└── directives
    ├── directive1
    │   ├── directive1.html
    │   ├── directive1.js
    │   └── directive1.sass
    └── directive2
        ├── directive2.html
        ├── directive2.js
        └── directive2.sass

Struktur tambahan ini bisa dikombinasikan dengan 2 struktur di atas.

Variasi Struktur: Seperti yang digunakan di proyek . Di dalam proyek tersebut, setiap unit testing ditempatkan dalam 1 direktori yang sama dengan komponen. Dengan cara tersebut, anda akan menemukannya dengan cepat dan juga bisa digunakan untuk dokumentasi dan cara penggunaan komponen tersebut.

services
├── cache
│   ├── cache1.js
│   └── cache1.spec.js
└── models
    ├── model1.js
    └── model1.spec.js

  • File
    .
    ├── app
    │   ├── app.js
    │   ├── common
    │   │   ├── controllers
    │   │   ├── directives
    │   │   ├── filters
    │   │   └── services
    │   ├── home
    │   │   ├── controllers
    │   │   │   ├── FirstCtrl.js
    │   │   │   └── SecondCtrl.js
    │   │   ├── directives
    │   │   │   └── directive1.js
    │   │   ├── filters
    │   │   │   ├── filter1.js
    │   │   │   └── filter2.js
    │   │   └── services
    │   │       ├── service1.js
    │   │       └── service2.js
    │   └── about
    │       ├── controllers
    │       │   └── ThirdCtrl.js
    │       ├── directives
    │       │   ├── directive2.js
    │       │   └── directive3.js
    │       ├── filters
    │       │   └── filter3.js
    │       └── services
    │           └── service3.js
    ├── partials
    ├── lib
    └── test
    
    8 berisi definisi routing dan konfigurasi.
  • Setiap file javascript, hanya boleh berisi sebuah komponen. File tersebut harus diberi nama sesuai nama komponen.
  • Alternatif lain, gunakan struktur seperti di Yeoman, .

Saya sendiri lebih menyukai struktur pertama, karena komponen lebih mudah dicari.

Untuk Aturan standar penamaan komponen bisa ditemukan di panduan tiap bagian.

Markup

TLDR; Letakan semua script di bagian bawah halaman.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>MyApp</title>
</head>
<body>
  <div ng-app="myApp">
    <div ng-view></div>
  </div>
  <script src="angular.js"></script>
  <script src="app.js"></script>
</body>
</html>

Buat semuanya simpel dan susun file dari yang sangat umum hingga directive yang spesifik di bagian akhir. Dengan begitu lebih mudah untuk melihat, mencari dan mengubahnya.

<form class="frm" ng-submit="login.authenticate()">
  <div>
    <input class="ipt" type="text" placeholder="name" require ng-model="user.name">
  </div>
</form>

Untuk atribut HTML yang lain, ikuti panduan

Optimasi "digest cycle"

  • Hanya 'watch' variabel vital (seperti: ketika menggunakan komunikasi real-time, jangan gunakan
    .
    ├── app
    │   ├── app.js
    │   ├── common
    │   │   ├── controllers
    │   │   ├── directives
    │   │   ├── filters
    │   │   └── services
    │   ├── home
    │   │   ├── controllers
    │   │   │   ├── FirstCtrl.js
    │   │   │   └── SecondCtrl.js
    │   │   ├── directives
    │   │   │   └── directive1.js
    │   │   ├── filters
    │   │   │   ├── filter1.js
    │   │   │   └── filter2.js
    │   │   └── services
    │   │       ├── service1.js
    │   │       └── service2.js
    │   └── about
    │       ├── controllers
    │       │   └── ThirdCtrl.js
    │       ├── directives
    │       │   ├── directive2.js
    │       │   └── directive3.js
    │       ├── filters
    │       │   └── filter3.js
    │       └── services
    │           └── service3.js
    ├── partials
    ├── lib
    └── test
    
    9 loop disetiap pesan yang diterima).
  • Untuk konten yang diinisialisasi sekali dan tidak pernah berubah lagi, gunakan 'single-time watchers' seperti
    app
    └── directives
        ├── directive1
        │   ├── directive1.html
        │   ├── directive1.js
        │   └── directive1.sass
        └── directive2
            ├── directive2.html
            ├── directive2.js
            └── directive2.sass
    
    0.
  • Buat komputasi di dalam
    app
    └── directives
        ├── directive1
        │   ├── directive1.html
        │   ├── directive1.js
        │   └── directive1.sass
        └── directive2
            ├── directive2.html
            ├── directive2.js
            └── directive2.sass
    
    1 se-simpel mungkin. Karena komputasi berat atau lambat di sebuah
    app
    └── directives
        ├── directive1
        │   ├── directive1.html
        │   ├── directive1.js
        │   └── directive1.sass
        └── directive2
            ├── directive2.html
            ├── directive2.js
            └── directive2.sass
    
    1 akan memperlambat seluruh aplikasimu.
  • Set false parameter ke 3 di
    app
    └── directives
        ├── directive1
        │   ├── directive1.html
        │   ├── directive1.js
        │   └── directive1.sass
        └── directive2
            ├── directive2.html
            ├── directive2.js
            └── directive2.sass
    
    3 untuk melewatkan
    .
    ├── app
    │   ├── app.js
    │   ├── common
    │   │   ├── controllers
    │   │   ├── directives
    │   │   ├── filters
    │   │   └── services
    │   ├── home
    │   │   ├── controllers
    │   │   │   ├── FirstCtrl.js
    │   │   │   └── SecondCtrl.js
    │   │   ├── directives
    │   │   │   └── directive1.js
    │   │   ├── filters
    │   │   │   ├── filter1.js
    │   │   │   └── filter2.js
    │   │   └── services
    │   │       ├── service1.js
    │   │       └── service2.js
    │   └── about
    │       ├── controllers
    │       │   └── ThirdCtrl.js
    │       ├── directives
    │       │   ├── directive2.js
    │       │   └── directive3.js
    │       ├── filters
    │       │   └── filter3.js
    │       └── services
    │           └── service3.js
    ├── partials
    ├── lib
    └── test
    
    9 loop ketika tidak ada lagi variabel yang harus di 'watch'.

Lain Lain

  • Gunakan:
    • app
      └── directives
          ├── directive1
          │   ├── directive1.html
          │   ├── directive1.js
          │   └── directive1.sass
          └── directive2
              ├── directive2.html
              ├── directive2.js
              └── directive2.sass
      
      3 daripada
      app
      └── directives
          ├── directive1
          │   ├── directive1.html
          │   ├── directive1.js
          │   └── directive1.sass
          └── directive2
              ├── directive2.html
              ├── directive2.js
              └── directive2.sass
      
      6
    • app
      └── directives
          ├── directive1
          │   ├── directive1.html
          │   ├── directive1.js
          │   └── directive1.sass
          └── directive2
              ├── directive2.html
              ├── directive2.js
              └── directive2.sass
      
      7 daripada
      app
      └── directives
          ├── directive1
          │   ├── directive1.html
          │   ├── directive1.js
          │   └── directive1.sass
          └── directive2
              ├── directive2.html
              ├── directive2.js
              └── directive2.sass
      
      8
    • app
      └── directives
          ├── directive1
          │   ├── directive1.html
          │   ├── directive1.js
          │   └── directive1.sass
          └── directive2
              ├── directive2.html
              ├── directive2.js
              └── directive2.sass
      
      9 daripada
      services
      ├── cache
      │   ├── cache1.js
      │   └── cache1.spec.js
      └── models
          ├── model1.js
          └── model1.spec.js
      
      0
    • services
      ├── cache
      │   ├── cache1.js
      │   └── cache1.spec.js
      └── models
          ├── model1.js
          └── model1.spec.js
      
      1 daripada
      services
      ├── cache
      │   ├── cache1.js
      │   └── cache1.spec.js
      └── models
          ├── model1.js
          └── model1.spec.js
      
      2
    • services
      ├── cache
      │   ├── cache1.js
      │   └── cache1.spec.js
      └── models
          ├── model1.js
          └── model1.spec.js
      
      3 daripada
      services
      ├── cache
      │   ├── cache1.js
      │   └── cache1.spec.js
      └── models
          ├── model1.js
          └── model1.spec.js
      
      4

Ini akan mempermudah testing dan akan mencegah kejadian tidak terduga (seperti, jika anda melewatkan

services
├── cache
│   ├── cache1.js
│   └── cache1.spec.js
└── models
    ├── model1.js
    └── model1.spec.js
5 di
app
└── directives
    ├── directive1
    │   ├── directive1.html
    │   ├── directive1.js
    │   └── directive1.sass
    └── directive2
        ├── directive2.html
        ├── directive2.js
        └── directive2.sass
6).

  • Otomatiskan sistem kerja anda dengan tool bantuan seperti:

    • Yeoman
    • Grunt
    • Bower
  • Gunakan promises (

    services
    ├── cache
    │   ├── cache1.js
    │   └── cache1.spec.js
    └── models
        ├── model1.js
        └── model1.spec.js
    
    7) daripada callbacks. Ini akan membuat kode anda lebih elegan dan bersih, dan menyelamatkan anda dari 'callback hell'.

  • Gunakan

    services
    ├── cache
    │   ├── cache1.js
    │   └── cache1.spec.js
    └── models
        ├── model1.js
        └── model1.spec.js
    
    8 daripada
    services
    ├── cache
    │   ├── cache1.js
    │   └── cache1.spec.js
    └── models
        ├── model1.js
        └── model1.spec.js
    
    3 jika memungkinkan. Semakin tinggi level abstraksi, akan menyelamatkan anda dari redudansi.

  • Gunakan AngularJS pre-minifier (seperti ngmin atau ng-annotate) untuk mencegah masalah setelah proses minifikasi.

  • Jangan gunakan variabel global. Selalu gunakan Dependency Injection.

  • Jangan kotori

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>MyApp</title>
    </head>
    <body>
      <div ng-app="myApp">
        <div ng-view></div>
      </div>
      <script src="angular.js"></script>
      <script src="app.js"></script>
    </body>
    </html>
    
    0. Hanya tambahkan fungsi dan variabel yang benar-benar akan digunakan.

  • Lebih baik inisialisasi variabel di controllers daripada menggunakan

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>MyApp</title>
    </head>
    <body>
      <div ng-app="myApp">
        <div ng-view></div>
      </div>
      <script src="angular.js"></script>
      <script src="app.js"></script>
    </body>
    </html>
    
    1. Hanya gunakan
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>MyApp</title>
    </head>
    <body>
      <div ng-app="myApp">
        <div ng-view></div>
      </div>
      <script src="angular.js"></script>
      <script src="app.js"></script>
    </body>
    </html>
    
    1 untuk aliasing di
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>MyApp</title>
    </head>
    <body>
      <div ng-app="myApp">
        <div ng-view></div>
      </div>
      <script src="angular.js"></script>
      <script src="app.js"></script>
    </body>
    </html>
    
    3.

  • Jangan gunakan awalan

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>MyApp</title>
    </head>
    <body>
      <div ng-app="myApp">
        <div ng-view></div>
      </div>
      <script src="angular.js"></script>
      <script src="app.js"></script>
    </body>
    </html>
    
    4 untuk nama variabel, properti dan fungsi. Awalan ini digunakan oleh AngularJS.

  • Ketika melakukan Depedency Injection, susun semuanya dimulai dari library AngularJS terlebih dahulu, setelah itu library kustom anda:

module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
  return {
    //Something
  };
});

Modules
  • Modules harus diberi nama dengan standar 'lowerCamelCase'. Apabila module
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>MyApp</title>
    </head>
    <body>
      <div ng-app="myApp">
        <div ng-view></div>
      </div>
      <script src="angular.js"></script>
      <script src="app.js"></script>
    </body>
    </html>
    
    5 adalah submodule dari module
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>MyApp</title>
    </head>
    <body>
      <div ng-app="myApp">
        <div ng-view></div>
      </div>
      <script src="angular.js"></script>
      <script src="app.js"></script>
    </body>
    </html>
    
    6, maka anda bisa menumpuknya dengan namespace seperti:
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>MyApp</title>
    </head>
    <body>
      <div ng-app="myApp">
        <div ng-view></div>
      </div>
      <script src="angular.js"></script>
      <script src="app.js"></script>
    </body>
    </html>
    
    7.

Ada 2 struktur umum untuk modul:

  1. Dari fungsionalitas
  2. Dari tipe komponen

Saat ini 2 struktur di atas tidak terlalu berbeda, tapi yang pertama lebih terlihat bersih. Namun, apabila module 'lazy-loading' sudah diimplementasikan (walaupun saat ini module tersebut tidak ada dalam roadmap tim AngularJS), struktur pertama dapat menambah performa aplikasi anda.

Controllers
  • Jangan memanipulasi DOM dari controller, akan membuat controller anda sulit di tes dan melawan prinsip Separation of Concerns. Lebih baik gunakan directive.
  • Untuk penamaan controller gunakan standar 'UpperCamelCase' dan harus sesuai dengan fungsionalitasnya (seperti: shopping cart, homepage, admin panel) dan diakhiri dengan
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>MyApp</title>
    </head>
    <body>
      <div ng-app="myApp">
        <div ng-view></div>
      </div>
      <script src="angular.js"></script>
      <script src="app.js"></script>
    </body>
    </html>
    
    8 (
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>MyApp</title>
    </head>
    <body>
      <div ng-app="myApp">
        <div ng-view></div>
      </div>
      <script src="angular.js"></script>
      <script src="app.js"></script>
    </body>
    </html>
    
    9,
    <form class="frm" ng-submit="login.authenticate()">
      <div>
        <input class="ipt" type="text" placeholder="name" require ng-model="user.name">
      </div>
    </form>
    
    0,
    <form class="frm" ng-submit="login.authenticate()">
      <div>
        <input class="ipt" type="text" placeholder="name" require ng-model="user.name">
      </div>
    </form>
    
    1, dll.).
  • Controller tidak boleh didefinisikan secara global (meskipun AngularJS mengijinkan hal ini, namun sangatlah tidak baik mengotori namespace global).
  • Gunakan syntax array untuk definisi controller:

module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyN', function (dependency1, dependency2, ..., dependencyN) {
  //...body
}]);

Gunakan cara definisi seperti ini untuk menghindarkan masalah minifikasi. Anda dapat secara otomatis menghasilkan definisi seperti di atas dengan menggunakan tool seperti ng-annotate (dan grunt task grunt-ng-annotate).

  • Gunakan nama asli dari Dependency Injection, ini akan memudahkanmu membaca kode:

module.controller('MyCtrl', ['$scope', function (s) {
  //...body
}]);

Akan lebih susah dimengerti daripada:

module.controller('MyCtrl', ['$scope', function ($scope) {
  //...body
}]);

Hal ini akan sangat berguna ketika file yang anda baca cukup panjang.

  • Buat controller sesimpel mungkin dan abstraksikan semua logika bisnis ke dalam service.
  • Komunikasi dengan controller yang berbeda menggunakan method invocation (memungkinkan ketika child controller ingin berkomunikasi dengan parent controller) atau
    <form class="frm" ng-submit="login.authenticate()">
      <div>
        <input class="ipt" type="text" placeholder="name" require ng-model="user.name">
      </div>
    </form>
    
    2,
    <form class="frm" ng-submit="login.authenticate()">
      <div>
        <input class="ipt" type="text" placeholder="name" require ng-model="user.name">
      </div>
    </form>
    
    3 dan
    <form class="frm" ng-submit="login.authenticate()">
      <div>
        <input class="ipt" type="text" placeholder="name" require ng-model="user.name">
      </div>
    </form>
    
    4. Pesan yang disebarkan harus seminimum mungkin.
  • Buatlah daftar semua pesan yang digunakan
    <form class="frm" ng-submit="login.authenticate()">
      <div>
        <input class="ipt" type="text" placeholder="name" require ng-model="user.name">
      </div>
    </form>
    
    2,
    <form class="frm" ng-submit="login.authenticate()">
      <div>
        <input class="ipt" type="text" placeholder="name" require ng-model="user.name">
      </div>
    </form>
    
    3 dan atur secara hati-hati untuk menghindari nama yang sama.
  • Ketika anda ingin mengubah format tampilan data, gunakan :

.
├── app
│   ├── app.js
│   ├── common
│   │   ├── controllers
│   │   ├── directives
│   │   ├── filters
│   │   └── services
│   ├── home
│   │   ├── controllers
│   │   │   ├── FirstCtrl.js
│   │   │   └── SecondCtrl.js
│   │   ├── directives
│   │   │   └── directive1.js
│   │   ├── filters
│   │   │   ├── filter1.js
│   │   │   └── filter2.js
│   │   └── services
│   │       ├── service1.js
│   │       └── service2.js
│   └── about
│       ├── controllers
│       │   └── ThirdCtrl.js
│       ├── directives
│       │   ├── directive2.js
│       │   └── directive3.js
│       ├── filters
│       │   └── filter3.js
│       └── services
│           └── service3.js
├── partials
├── lib
└── test
0

  • Untuk controller yang bertumpuk, gunakan "nested scoping" dengan
    <form class="frm" ng-submit="login.authenticate()">
      <div>
        <input class="ipt" type="text" placeholder="name" require ng-model="user.name">
      </div>
    </form>
    
    7:

app.js

.
├── app
│   ├── app.js
│   ├── common
│   │   ├── controllers
│   │   ├── directives
│   │   ├── filters
│   │   └── services
│   ├── home
│   │   ├── controllers
│   │   │   ├── FirstCtrl.js
│   │   │   └── SecondCtrl.js
│   │   ├── directives
│   │   │   └── directive1.js
│   │   ├── filters
│   │   │   ├── filter1.js
│   │   │   └── filter2.js
│   │   └── services
│   │       ├── service1.js
│   │       └── service2.js
│   └── about
│       ├── controllers
│       │   └── ThirdCtrl.js
│       ├── directives
│       │   ├── directive2.js
│       │   └── directive3.js
│       ├── filters
│       │   └── filter3.js
│       └── services
│           └── service3.js
├── partials
├── lib
└── test
1

HomeCtrl

.
├── app
│   ├── app.js
│   ├── common
│   │   ├── controllers
│   │   ├── directives
│   │   ├── filters
│   │   └── services
│   ├── home
│   │   ├── controllers
│   │   │   ├── FirstCtrl.js
│   │   │   └── SecondCtrl.js
│   │   ├── directives
│   │   │   └── directive1.js
│   │   ├── filters
│   │   │   ├── filter1.js
│   │   │   └── filter2.js
│   │   └── services
│   │       ├── service1.js
│   │       └── service2.js
│   └── about
│       ├── controllers
│       │   └── ThirdCtrl.js
│       ├── directives
│       │   ├── directive2.js
│       │   └── directive3.js
│       ├── filters
│       │   └── filter3.js
│       └── services
│           └── service3.js
├── partials
├── lib
└── test
2

template.html

.
├── app
│   ├── app.js
│   ├── common
│   │   ├── controllers
│   │   ├── directives
│   │   ├── filters
│   │   └── services
│   ├── home
│   │   ├── controllers
│   │   │   ├── FirstCtrl.js
│   │   │   └── SecondCtrl.js
│   │   ├── directives
│   │   │   └── directive1.js
│   │   ├── filters
│   │   │   ├── filter1.js
│   │   │   └── filter2.js
│   │   └── services
│   │       ├── service1.js
│   │       └── service2.js
│   └── about
│       ├── controllers
│       │   └── ThirdCtrl.js
│       ├── directives
│       │   ├── directive2.js
│       │   └── directive3.js
│       ├── filters
│       │   └── filter3.js
│       └── services
│           └── service3.js
├── partials
├── lib
└── test
3

Directives
  • Gunakan standar penamaan 'lowerCamelCase'.
  • Gunakan
    <form class="frm" ng-submit="login.authenticate()">
      <div>
        <input class="ipt" type="text" placeholder="name" require ng-model="user.name">
      </div>
    </form>
    
    8 daripada
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>MyApp</title>
    </head>
    <body>
      <div ng-app="myApp">
        <div ng-view></div>
      </div>
      <script src="angular.js"></script>
      <script src="app.js"></script>
    </body>
    </html>
    
    0 di dalam link function. Pada saat proses kompilasi, post/pre link function yang telah didefinisikan dengan argumen, akan diberikan ketika fungsi tersebut dipanggil, anda tidak akan dapat mengubahnya dengan Dependency Injection. Cara ini juga digunakan di kode sumber AngularJS.
  • Gunakan awalan yang berbeda untuk directive, untuk mencegah error karena penggunaan nama yang sama dengan third-party library.
  • Jangan gunakan awalan
    module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
      return {
        //Something
      };
    });
    0 atau
    module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
      return {
        //Something
      };
    });
    1 karena telah digunakan untuk AngularJS dan AngularJS UI.
  • Manipulasi DOM hanya dilakukan di dalam directive.
  • Usahakan scope harus terisolasi ketika membuat komponen yang bisa digunakan kembali.
  • Gunakan directive di atribut atau elemen daripada di komentar atau class, ini akan membuat kode lebih mudah dibaca.
  • Gunakan
    module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
      return {
        //Something
      };
    });
    2 untuk membersihkan. Sangat berguna terutama ketika anda menggunakan third-party plugin sebagai directive.
  • Jangan lupa gunakan
    module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
      return {
        //Something
      };
    });
    3 untuk konten yang tidak dapat dipercaya.
Filters
  • Gunakan standar penamaan 'lowerCamelCase'.
  • Buat filter anda se-ringan mungkin karena sering dipanggil selama
    .
    ├── app
    │   ├── app.js
    │   ├── common
    │   │   ├── controllers
    │   │   ├── directives
    │   │   ├── filters
    │   │   └── services
    │   ├── home
    │   │   ├── controllers
    │   │   │   ├── FirstCtrl.js
    │   │   │   └── SecondCtrl.js
    │   │   ├── directives
    │   │   │   └── directive1.js
    │   │   ├── filters
    │   │   │   ├── filter1.js
    │   │   │   └── filter2.js
    │   │   └── services
    │   │       ├── service1.js
    │   │       └── service2.js
    │   └── about
    │       ├── controllers
    │       │   └── ThirdCtrl.js
    │       ├── directives
    │       │   ├── directive2.js
    │       │   └── directive3.js
    │       ├── filters
    │       │   └── filter3.js
    │       └── services
    │           └── service3.js
    ├── partials
    ├── lib
    └── test
    
    9 loop.
  • Fokus lakukan 1 hal saja untuk setiap filter. Untuk manipulasi lebih kompleks, lebih baik menggabungkan beberapa filter sekaligus.
Services

Bagian ini adalah informasi tentang komponen service secara umum di AngularJS dan tidak spesifik tentang (

module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
  return {
    //Something
  };
});
5,
module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
  return {
    //Something
  };
});
6 atau
module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
  return {
    //Something
  };
});
7), kecuali ditegaskan demikian.

  • Gunakan standar penamaan 'camelCase'.

    • UpperCamelCase (PascalCase) untuk nama service apabila digunakan sebagai konstruktor, seperti:

      .
      ├── app
      │   ├── app.js
      │   ├── common
      │   │   ├── controllers
      │   │   ├── directives
      │   │   ├── filters
      │   │   └── services
      │   ├── home
      │   │   ├── controllers
      │   │   │   ├── FirstCtrl.js
      │   │   │   └── SecondCtrl.js
      │   │   ├── directives
      │   │   │   └── directive1.js
      │   │   ├── filters
      │   │   │   ├── filter1.js
      │   │   │   └── filter2.js
      │   │   └── services
      │   │       ├── service1.js
      │   │       └── service2.js
      │   └── about
      │       ├── controllers
      │       │   └── ThirdCtrl.js
      │       ├── directives
      │       │   ├── directive2.js
      │       │   └── directive3.js
      │       ├── filters
      │       │   └── filter3.js
      │       └── services
      │           └── service3.js
      ├── partials
      ├── lib
      └── test
      
      4

    • lowerCamelCase untuk semua service yang lain.

  • Enkapsulasikan semua logika bisnis di dalam service.

  • Service yang merepresentasikan domain lebih baik adalah

    module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
      return {
        //Something
      };
    });
    8 daripada
    module.factory('Service', function ($rootScope, $timeout, MyCustomDependency1, MyCustomDependency2) {
      return {
        //Something
      };
    });
    9. Dengan begitu kita dapat lebih mudah mendapatkan keuntungan dari "klassical" inheritance:

.
├── app
│   ├── app.js
│   ├── common
│   │   ├── controllers
│   │   ├── directives
│   │   ├── filters
│   │   └── services
│   ├── home
│   │   ├── controllers
│   │   │   ├── FirstCtrl.js
│   │   │   └── SecondCtrl.js
│   │   ├── directives
│   │   │   └── directive1.js
│   │   ├── filters
│   │   │   ├── filter1.js
│   │   │   └── filter2.js
│   │   └── services
│   │       ├── service1.js
│   │       └── service2.js
│   └── about
│       ├── controllers
│       │   └── ThirdCtrl.js
│       ├── directives
│       │   ├── directive2.js
│       │   └── directive3.js
│       ├── filters
│       │   └── filter3.js
│       └── services
│           └── service3.js
├── partials
├── lib
└── test
5

  • Untuk cache pada level session gunakan
    module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyN', function (dependency1, dependency2, ..., dependencyN) {
      //...body
    }]);
    0. Ini harus digunakan untuk meng-cache hasil dari request atau komputasi yang berat.
  • Jika sebuah service membutuhkan konfigurasi, maka definisikan service tersebut sebagai provider dan konfigurasikan service itu di dalam
    module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyN', function (dependency1, dependency2, ..., dependencyN) {
      //...body
    }]);
    1 callback seperti:

.
├── app
│   ├── app.js
│   ├── common
│   │   ├── controllers
│   │   ├── directives
│   │   ├── filters
│   │   └── services
│   ├── home
│   │   ├── controllers
│   │   │   ├── FirstCtrl.js
│   │   │   └── SecondCtrl.js
│   │   ├── directives
│   │   │   └── directive1.js
│   │   ├── filters
│   │   │   ├── filter1.js
│   │   │   └── filter2.js
│   │   └── services
│   │       ├── service1.js
│   │       └── service2.js
│   └── about
│       ├── controllers
│       │   └── ThirdCtrl.js
│       ├── directives
│       │   ├── directive2.js
│       │   └── directive3.js
│       ├── filters
│       │   └── filter3.js
│       └── services
│           └── service3.js
├── partials
├── lib
└── test
6

Templates
  • Gunakan
    module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyN', function (dependency1, dependency2, ..., dependencyN) {
      //...body
    }]);
    2 atau
    module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyN', function (dependency1, dependency2, ..., dependencyN) {
      //...body
    }]);
    3 daripada
    module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyN', function (dependency1, dependency2, ..., dependencyN) {
      //...body
    }]);
    4 untuk mencegah konten yang berkedip (flashing content).
  • Hindari menulis ekspresi yang kompleks di dalam template.
  • Gunakan
    module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyN', function (dependency1, dependency2, ..., dependencyN) {
      //...body
    }]);
    5 dan
    module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyN', function (dependency1, dependency2, ..., dependencyN) {
      //...body
    }]);
    4 daripada hanya
    module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyN', function (dependency1, dependency2, ..., dependencyN) {
      //...body
    }]);
    7
  • Gunakan
    module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyN', function (dependency1, dependency2, ..., dependencyN) {
      //...body
    }]);
    8 daripada
    module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyN', function (dependency1, dependency2, ..., dependencyN) {
      //...body
    }]);
    7 dan
    module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyN', function (dependency1, dependency2, ..., dependencyN) {
      //...body
    }]);
    4
  • Gunakan
    module.controller('MyCtrl', ['$scope', function (s) {
      //...body
    }]);
    1 daripada
    module.controller('MyCtrl', ['$scope', function (s) {
      //...body
    }]);
    2 dan
    module.controller('MyCtrl', ['dependency1', 'dependency2', ..., 'dependencyN', function (dependency1, dependency2, ..., dependencyN) {
      //...body
    }]);
    4

.
├── app
│   ├── app.js
│   ├── common
│   │   ├── controllers
│   │   ├── directives
│   │   ├── filters
│   │   └── services
│   ├── home
│   │   ├── controllers
│   │   │   ├── FirstCtrl.js
│   │   │   └── SecondCtrl.js
│   │   ├── directives
│   │   │   └── directive1.js
│   │   ├── filters
│   │   │   ├── filter1.js
│   │   │   └── filter2.js
│   │   └── services
│   │       ├── service1.js
│   │       └── service2.js
│   └── about
│       ├── controllers
│       │   └── ThirdCtrl.js
│       ├── directives
│       │   ├── directive2.js
│       │   └── directive3.js
│       ├── filters
│       │   └── filter3.js
│       └── services
│           └── service3.js
├── partials
├── lib
└── test
7

Routing
  • Gunakan
    module.controller('MyCtrl', ['$scope', function (s) {
      //...body
    }]);
    4 untuk resolve dependencies sebelum view ditampilkan.
Testing

TBD

Sampai bagian ini selesai, anda bisa menggunakan panduan ini terlebih dahulu.

Kontribusi

Karena panduan ini dibuat oleh komunitas, kontribusi sangatlah dihargai. Contohnya, anda dapat berkontribusi dengan memperluas bagian testing atau dengan menerjemahkan panduan ini ke dalam bahasa anda.