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

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

Opublikowano 24.04.2017 10:14 Aktualizacja: 24.04.2017 10:28 - 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:

[js]
(function () {
‘use strict’;
angular
.module(‘commentBox’)
.directive(‘reply’, ReplyDirective);

function ReplyDirective() {
return {
restrict: ‘E’,
templateUrl: ‘commentBox/reply/reply.html’
};
}
})();
[/js]

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:

[html]

<div class="comment__reply">

<div class="reply__content">

{{reply.author}}

{{reply.text}}

</div>

</div>

[/html]

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.

[html]

<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>

[/html]

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.

[html]

<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>

[/html]

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

[js]
(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!’
}
];
}
})();
[/js]

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:

[js]
(function () {
‘use strict’;
angular.module(‘commentBox’, []);
})();
[/js]

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]
<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>

[/html]

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

Autorem wpisu jest Paweł Płoneczka.

Wieści z Rozładowani.pl

[s_button url="https://dailyweb.pl/szukamy-redaktorow-do-dailyweb/" target="blank" style="flat" background="#3cbe75" size="5" center="yes" radius="0" icon="icon: share-square-o"]Zobacz[/s_button]