Haruskah arahan angularj langsung berinteraksi dengan layanan atau itu dianggap sebagai anti-pola?

35

Mana yang dianggap lebih baik:

  • memiliki arahan yang berinteraksi dengan layanan secara langsung

atau

  • memiliki arahan yang mengekspos kait tertentu yang controller dapat mengikat perilaku (melibatkan layanan)?
WTK
sumber
Saya perlu konteks yang lebih sedikit tentang apa yang ingin Anda capai, apa yang dikomunikasikan, berapa banyak kode sumber yang diharapkan dari domain Anda, bagaimana skalanya?
Pengguna
Ini adalah arahan yang bertanggung jawab untuk membuat widget komentar - ini menampilkan kolom komentar, bersama dengan tombol kirim / batal. Arahan ini seharusnya digunakan hanya dalam satu konteks - mengomentari "dokumen". Cara itu saat ini ditangani controller adalah mengekspos fungsi untuk membuat komentar aktual (controller mendapatkan contoh layanan komentar). Cara lain untuk melakukannya adalah merangkum semua hal (bersama dengan penanganan kesalahan / keberhasilan) dalam sebuah arahan (arahan akan mendapatkan layanan komentar disuntikkan).
WTK

Jawaban:

24

Arahan adalah yang terbaik (sebagai patokan) jika pendek (berdasarkan kode), (berpotensi) dapat digunakan kembali, dan memiliki ruang lingkup terbatas dalam hal fungsionalitas. Membuat arahan yang mencakup UI dan tergantung pada layanan (yang saya asumsikan menangani koneksi ke backend), tidak hanya memberikannya 2 peran fungsional, yaitu:

  • Mengontrol UI untuk tampilan / entri data untuk widget.
  • Mengirimkan ke backend (melalui layanan).

tetapi juga membuatnya kurang dapat digunakan kembali, karena Anda kemudian tidak dapat menggunakannya lagi dengan layanan lain, atau dengan UI yang berbeda (setidaknya tidak mudah).

Saat membuat keputusan ini, saya sering membandingkan dengan elemen HTML bawaan: misalnya <input>, <textarea>atau <form>: mereka sepenuhnya independen dari backend spesifik. HTML5 telah memberikan <input>elemen beberapa tipe tambahan, misalnya date, yang masih independen dari backend, dan ke mana tepatnya data berjalan atau bagaimana ia digunakan. Mereka murni elemen antarmuka. Widget khusus Anda, dibuat menggunakan arahan, saya pikir harus mengikuti pola yang sama, jika memungkinkan.

Namun, ini bukan akhir dari cerita. Melampaui analogi dengan elemen HTML built-in, Anda dapat membuat arahan yang dapat digunakan kembali yang keduanya memanggil layanan, dan menggunakan arahan UI murni, sama seperti itu mungkin menggunakan a <textarea>. Katakanlah Anda ingin menggunakan beberapa HTML sebagai berikut:

<document document-url="'documents/3345.html'">
 <document-data></document-data>
 <comments></comments>
 <comment-entry></comment-entry>
</document>

Untuk menyusun commentEntryarahan, Anda bisa membuat arahan yang sangat kecil yang hanya berisi pengontrol yang menghubungkan layanan dengan widget UI. Sesuatu seperti:

app.directive('commentEntry', function (myService) {
  return {
    restrict: 'E',
    template: '<comment-widget on-save="save(data)" on-cancel="cancel()"></comment-widget>',
    require: '^document',
    link: function (scope, iElement, iAttrs, documentController) {
      // Allow the controller here to access the document controller
      scope.documentController = documentController;
    },
    controller: function ($scope) {
      $scope.save = function (data) {
        // Assuming the document controller exposes a function "getUrl"
        var url = $scope.documentController.getUrl(); 

        myService.saveComments(url, data).then(function (result) {
          // Do something
        });
      };
    }
  };
});

Membawa ini ke ekstrem, Anda mungkin tidak perlu memiliki ng-controlleratribut manual dalam HTML: Anda dapat melakukan semuanya menggunakan arahan, selama masing-masing secara langsung memiliki peran "UI" yang jelas, atau peran "data" yang jelas.

Ada kekurangan yang harus saya sebutkan: itu memberikan lebih banyak "bagian yang bergerak" ke aplikasi, yang menambah sedikit kompleksitas. Namun, jika masing-masing bagian memiliki peran yang jelas, dan baik (unit + E2E diuji), saya berpendapat itu layak dan manfaat keseluruhan dalam jangka panjang.

Michal Charemza
sumber
59

Izinkan saya untuk tidak setuju dengan jawaban Michal Charemza.

Meskipun jawabannya secara teori benar, itu tidak terlalu praktis untuk dunia nyata.

Saya mengatakan itu karena saya dulu berpikir seperti itu dan mencoba menerapkannya pada aplikasi dunia nyata besar yang saya dan tim saya sedang bangun dan itu menjadi terlalu merepotkan.

Analogi dengan bahasa HTML tidak baik, karena Anda tidak harus berusaha untuk membangun tujuan umum, arahan yang sangat dapat digunakan kembali, karena Anda tidak membangun aplikasi generik seperti browser web.

Alih-alih, Anda harus menggunakan arahan untuk membangun Domain Specific Language (DSL) untuk aplikasi Anda, yang hidup di domainnya sendiri.

Itu tidak berarti bahwa semua arahan tidak boleh generik. Beberapa mungkin, jika itu sifatnya. Jika Anda sedang membuat pemilih tanggal kustom, tentu saja membuatnya generik dan dapat digunakan kembali di seluruh aplikasi.

Tetapi jika Anda sedang membangun sesuatu seperti kotak login yang mengikat back-end Anda, lakukan saja.

Satu-satunya aturan praktis adalah: jangan pernah menduplikasi kode (potongan kecil abstrak ke pabrik dan jasa) dan membuatnya dapat diuji melalui injeksi ketergantungan. Untungnya, dengan Angular, itu adalah sepotong kue.

Tetap sederhana. :)

Dema
sumber
5
Poin bagus Dema - meskipun saya menerima jawaban Michal, saya setuju dengan pendekatan Anda, bahwa kita tidak boleh melompat untuk membuat sesuatu yang dapat digunakan kembali hanya demi itu. Itulah insting awal saya untuk mengikat layanan dengan arahan, karena itu masuk akal, bukan karena bagaimana guru angular mau atau tidak melakukannya. Pada akhirnya saya membuat arahan dengan layanan yang disuntikkan langsung ke dalamnya, dan sebagai API publik saya memberikan pengait untuk panggilan balik yang diaktifkan setelah komentar benar-benar dibuat.
WTK
2

Saya pikir pertanyaan "harusnya direktif berinteraksi dengan layanan" tergantung pada apa yang dilakukan layanan Anda.

Saya memiliki arahan yang berinteraksi dengan layanan yang tidak melakukan apa pun dengan permintaan HTTP dan saya pikir itu adalah pola yang baik. Layanan / Pabrik sangat bagus untuk merangkum lebih banyak logika yang berorientasi data, dan arahan sangat bagus untuk merangkum logika berorientasi presentasi. Tujuan layanan yang disebutkan dalam dokumen Angular adalah: "Anda dapat menggunakan layanan untuk mengatur dan berbagi kode di seluruh aplikasi Anda.". Itu cukup luas tetapi layanan dapat digunakan untuk mencapai tujuan itu dalam arahan.

Yang sedang berkata, saya mengerti keinginan dalam beberapa kasus untuk membuatnya sehingga arahan tidak secara langsung membuat permintaan HTTP. Sekali lagi, itu tergantung pada layanan dan bagaimana Anda mengatur layanan Anda.

ccnokes
sumber
1

Sesuai kerangka kerja AngularJS, kita harus memilih pabrik / layanan tunggal untuk mendapatkan data dari server. Sehingga pabrik-pabrik ini dapat digunakan kembali di seluruh aplikasi tanpa menulis ulang yang sama. Nah di dalam direktif kita dapat memanggil pabrik-pabrik ini untuk mendapatkan data yang diambil dari Api / server.

Basavaraj Kabuure
sumber