Angularjs direktifi hizmetler ile doğrudan etkileşime girmeli midir, yoksa bir anti-kalıp olarak mı kabul edilir?


35

Hangisi daha iyi kabul edilir:

  • doğrudan hizmetlerle etkileşime giren bir yönetmeliğe sahip olmak

veya

  • Hangi kontrol ünitesinin davranışları bağlayabileceği belirli kancaları ortaya çıkaran bir yönerge kullanmak (hizmetleri içeren)?

Ne elde etmek istediğinizi, ne iletildiğini, ne kadar kaynak kodunun beklenebileceğini biraz etkilemeliyim, etki alanınız nedir, nasıl ölçeklendirmesi gerekiyor?
Kullanıcı

Bir yorum widget'ı oluşturmaktan sorumlu bir yönerge - yorum / iptal düğmeleriyle birlikte yorum alanını görüntüler. Bu yönerge sadece bir bağlamda kullanılmalıdır - "belge" hakkında yorum. Halen denetleyiciyi kullanma şekli, gerçek yorum oluşturma işlevlerini ortaya koyuyor (denetleyicinin enjekte edilen yorum hizmeti örneği). Bunu yapmanın başka bir yolu da her şeyi (hata / başarı yönetimi ile birlikte) bir direktifle kapsıyor (direktif yorum servisine enjekte edilir).
WTK,

Yanıtlar:


24

Bir yönerge en iyisidir (kural olarak) kısa (kodlu), (potansiyel olarak) tekrar kullanılabilir olduğunda ve işlevsellik açısından sınırlı bir kapsamı olduğunda. UI içeren ve bir servise bağlı olan bir yönerge yapmak (arka uçla bağlantıyı ele aldığımı farz ediyorum), sadece 2 işlevsel rol vermekle kalmaz, yani:

  • Pencere aracına ilişkin verilerin görüntülenmesi / girilmesi için kullanıcı arayüzünü denetleme
  • Arka uca gönderme (servis aracılığıyla).

aynı zamanda daha az tekrar kullanılabilir hale getirilmesi, başka bir hizmetle veya farklı bir UI ile (en azından kolay değil) tekrar kullanamayacağınız için tekrar kullanılabilir hale getirilmesi.

Bu kararları alırken, genellikle yerleşik HTML öğelerini karşılaştırırım: örneğin <input>, <textarea>veya <form>: belirli bir arka uçtan tamamen bağımsızdırlar. HTML5, <input>öğeye birkaç ek tür vermiştir , örneğin date, arka uçtan bağımsızdır ve verilerin tam olarak nereye gittiğini veya nasıl kullanıldığını. Onlar tamamen arayüz elemanlarıdır. Özel widget'larınız, direktifler kullanılarak oluşturulmuş, mümkünse aynı modeli izlemesi gerektiğini düşünüyorum.

Ancak, bu hikayenin sonu değil. Yerleşik HTML öğeleriyle analojinin ötesine geçerek, her iki hizmeti de çağıran yeniden kullanılabilir yönergeler oluşturabilir ve tıpkı kullanabileceği gibi tamamen bir UI yönergesi kullanabilirsiniz <textarea>. Bazı HTML’leri aşağıdaki gibi kullanmak istediğinizi söyleyin:

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

Yönergeyi kodlamak için, commentEntryyalnızca bir hizmeti bir UI widget'ına bağlayan denetleyiciyi içeren çok küçük bir yönergeyi yapabilirsiniz. Gibi bir şey:

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

Bunu uç noktalara ng-controllertaşıyarak, HTML’de manuel bir öznitelik sahibi olmanız gerekmeyebilir : her biri doğrudan bir "UI" rolü veya açık bir "veri" rolü olduğu sürece, yönergeleri kullanarak tüm bunları yapabilirsiniz.

Bahsetmem gereken bir olumsuzluk var: uygulamaya biraz daha karmaşıklık katan, daha fazla "hareketli parça" veriyor. Ancak, eğer her bir parçanın net bir rolü varsa ve iyiyse (birim + E2E test edilmiştir), buna değeceğini ve uzun vadede genel bir fayda olduğunu iddia ediyorum.


59

Michal Charemza'nın cevabına katılmama izin ver.

Cevabı teorik olarak doğru olmasına rağmen, gerçek dünya için pek pratik değildir.

Öyle söylüyorum çünkü böyle düşünürdüm ve büyük bir gerçek dünya uygulamasında kendim ve ekibimin inşa ettiği ve çok zahmetli bir hale getirmeye çalıştım.

HTML diline benzetme iyi değildir, çünkü genel amaçlı, son derece yeniden kullanılabilir yönergeler oluşturmak için çabalamamalısınız, çünkü bir web tarayıcısı gibi genel bir uygulama oluşturmuyorsunuz.

Bunun yerine, uygulamanız için kendi etki alanında bulunan bir Etki Alanı Özel Dili (DSL) oluşturmak için yönergeleri kullanmalısınız.

Bu, tüm direktiflerin genel olmaması gerektiği anlamına gelmez. Bazıları, eğer onların doğasında ise olabilir. Özel bir tarih seçici oluşturuyorsanız, elbette uygulamaları genel ve yeniden kullanılabilir hale getirin.

Ancak, arka tarafınıza bağlanan bir giriş kutusu gibi bir şey inşa ediyorsanız, sadece yapın.

Tek kural kuralı şöyle olmalıdır: kodu asla kopyalamayın (fabrikalara ve hizmetlere küçük parçalar koyun) ve bağımlılık enjeksiyonuyla test edilebilir hale getirmeyin. Neyse ki, Angular ile bunlar çok kolay.

Basit tut. :)


5
İyi noktalar Dema - Michal'ın cevabını kabul etsem de, yaklaşımınıza katılıyorum, sadece bunun için tekrar kullanılabilir bir şey yapmak için çemberlere atlamamalıyız. Bu benim ilk içgüdümdü, hizmeti direktifle bağlamaktı, çünkü mantıklıydı, gurunun yapacağı ya da yapamadığı için değil. Sonunda doğrudan içine enjekte edilen servisle direktif oluşturdum ve herkese açık bir API olarak yorumlar oluşturulduktan sonra başlatılan bir geri çağırma için bir kanca hazırladım.
WTK

2

Bence "bir yönerge bir hizmetle etkileşime girmeli" sorusu hizmetinizin ne yaptığına bağlıdır.

Yönergeler, HTTP istekleriyle hiçbir şey yapmayan servislerle etkileşime girdi ve bunun iyi bir model olduğunu düşünüyorum. Servisler / Fabrikalar daha fazla veri odaklı mantığı içine almak için mükemmeldir ve direktifler sunum odaklı mantığı içine almak için mükemmeldir. Açısal dokümanlardaki servislerin belirtilen amacı: "Uygulamanızdaki kodu düzenlemek ve paylaşmak için hizmetleri kullanabilirsiniz.". Bu oldukça geniş, ancak direktiflerde bu amaca ulaşmak için hizmetler kullanılabilir.

Bununla birlikte, bazı durumlarda direktiflerin doğrudan herhangi bir HTTP isteğinde bulunmaması için bunu yapma arzusunu anlıyorum. Yine, hizmete ve hizmetlerinizi nasıl organize ettiğinize bağlıdır.


1

AngularJS çerçevesine göre, sunucudan veri almak için fabrikaları / hizmetleri tekilleştirmeliyiz. Böylece bu fabrikalar aynı yeniden yazmadan uygulamada yeniden kullanılabilirler. Direktifin içindeyken bu fabrikaları Api / sunucudan alınan verileri almak için arayabiliriz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.