DIY #15 Angular directives - tutorial jak zrobić prosty system komentarzy | DailyWeb.pl - codziennie o sieci

DIY #15 Angular directives - tutorial jak zrobić prosty system komentarzy

Opublikowano 5 miesięcy temu - 1


Chciałem wam dzisiaj przedstawić dyrektywy w praktyce. We wcześniejszym tutorialu (pierwsza dyrektywa w Angular) pokazałem, jak może wyglądać przykładowy kod systemu komentarzy. Dzisiaj pokażę wam jak to osiągnąć w praktyce. Dzięki uprzejmości Łukasza będziemy mieli ładny HTML do pracy (teraz już nikt nie powie, że robimy na brzydkim HTML ;) ). Gotowy HTML i CSS możecie znaleźć tutaj, a tak prezentuje się na żywo:

Na pierwszy rzut oka widać, że sporo elementów jest powtarzalnych. Możemy wykorzystać do tego celu kilku dyrektyw. Taki podział proponuje.

  • commentBox
  • addComment
  • comment
  • addReply
  • reply

Powyższy podział będzie wyglądać tak:

Wybaczcie, moje umiejętności painta nie są specjalnie mocne. Zaznaczyłem każdą z dyrektyw tylko raz. W taki oto sposób będziemy wycinać z całościowego HTML kawałki do podziału na dyrektywy. Cały moduł nazwiemy commentBox z uwagi, że będzie on zawierał commentBox. Logiczne?

Zaczynając od najniższej w hierarchii, czyli reply:

  (function () {
  'use strict';
  angular
    .module('commentBox')
    .directive('reply', ReplyDirective);

  function ReplyDirective() {
    return {
      restrict: 'E',
      templateUrl: 'commentBox/reply/reply.html'
    };
  }
})();

Lekka modyfikacja kodu względem poprzednich tutoriali. Cały kod dyrektywy został wydzielony do osobnego pliku js oraz owinięty w funkcję. Pojawiło się również ‚use strict’;. Wszystko to składa się na dobre praktyki pisania kodu. Nie będę rozwodzić się nad każdym z tych elementów, jeśli ktoś jest głodny wiedzy, podrzucam linki (1 2). Dalej można zauważyć, że zmieniła się deklaracja funkcji dyrektywy. Nie używamy już funkcji anonimowej, jak wcześniej, a definiujemy ją poniżej.
Kod HTML dyrektywy wygląda natomiast tak:


<div class="comment__reply">

<div class="reply__content">


{{reply.author}}



{{reply.text}}

</div>

</div>

Wyświetlamy treść odpowiedzi z obiektu reply (jak tam trafił, opiszę poniżej). Pliki z kodem dyrektywy wrzucamy do osobnego katalogu. Proponuję utworzyć główny katalog commentBox i dodać do niego katalog reply a w nim reply.js oraz reply.html, pozwala to na lepszą organizację kodu.

Z uwagi na to, że wszystkie dyrektywy będą różniły się tylko kodem HTML i nazwami funkcji pominę listingi niektórych z nich. Zobaczmy teraz, jak powinien wyglądać template dyrektywy comment.


<div class="comment">

<div class="comment__content">
{{comment.author}}
{{comment.text}}
  </div>

  <add-reply></add-reply>
  <reply ng-repeat="reply in comment.replies"></reply>
</div>

Analogicznie do reply wyświetlamy autora i treść komentarza. Dodatkowo wyświetlamy dyrektywę <add-reply> oraz <reply> w pętli iterując po wszystkich odpowiedziach.

Teraz czas na poskładanie wszystkiego w całość, a więc commentBox. Kod JS pomijam, bo jest analogiczny do reply. Poza nim tworzymy plik html z templatem.


<div class="comment__box" ng-controller="CommentBoxController as ctrl">

<h1>Dailyweb black and white comments module</h1>


<hr>

  <add-comment></add-comment>
  <comment ng-repeat="comment in ctrl.comments"></comment>
</div>

Analogicznie do comment wyświetlamy oraz w pętli po komentarzach znajdujących się w kontrolerze. Kontrolerze, którego kod wygląda tak:

(function () {
  'use strict';
  angular.module('commentBox')
    .controller('CommentBoxController', CommentBoxController);

  function CommentBoxController() {
    var ctrl = this;

    //static comment data
    ctrl.comments = [
      {
        author: 'Jack Sparrow',
        text: 'Damn M8, this is great!',
        replies: [
          {
            author: 'John Doe',
            text: 'Thx, dooing my best ;)'
          },
          {
            author: 'Trinity',
            text: 'I like trains 🚆'
          }
        ]
      },
      {
        author: 'William DeThoe',
        text: 'Before 301!',
        replies: [
          {
            author: 'Trinity',
            text: 'I like trains'
          }
        ]
      },
      {
        author: 'Jack Sparrow',
        text: 'Damn M8, this is great!'
      }
    ];
  }
})();

Jest również zdefiniowany w nowy sposób, dodatkowo nie używamy scope, tylko przypisujemy wszystko do samego kontrolera. Nic specjalnego w nim się nie dzieje, po prostu ustawiamy statyczne dane komentarzy. W tym miejscu powinno być wywołanie ładowania danych (np. z REST API). Plik z kontrolerem proponuję nazwać commentBox.controller.js i umieścić w folderze commentBox.

na sam koniec został nam do zdefiniowania nasz moduł commentBox. Proponuję utworzyć go w pliku commentBox.module.js w katalogu commentBox:

(function () {
  'use strict';
  angular.module('commentBox', []);
})();

Do uruchomienia całości będzie nam oczywiście potrzebny plik index.html w którym, wywołamy oraz sama biblioteka angulara. Ja posiłkowałem się npm do zainstalowania angulara ale możecie go zwyczajnie pobrać i osadzić w html. Mój plik index.html wygląda tak:

<html ng-app="commentBox">
<head>
  <title>System komentarzy</title>
  <link href="style.css" rel="stylesheet">

  <script src="node_modules/angular/angular.js"></script>
  <script src="commentBox/commentBox.module.js"></script>
  <script src="commentBox/commentBox.js"></script>
  <script src="commentBox/commentBox.controller.js"></script>
  <script src="commentBox/comment/comment.js"></script>
  <script src="commentBox/reply/reply.js"></script>
  <script src="commentBox/addComment/addComment.js"></script>
  <script src="commentBox/addReply/addReply.js"></script>
</head>

<body>

<comment-box></comment-box>

</body>
</html>

Całość kodu możecie znaleźć na Github.

Autorem wpisu jest Paweł Płoneczka.