Lekce 8 - Jednoduchý redakční systém v AngularJS - Administrace

JavaScript Angular Jednoduchý redakční systém v AngularJS - Administrace

ONEbit hosting Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, Jednoduchý redakční systém v AngularJS - Výpis článku, jsme již vytvořili základní strukturu pro výpis článků. Dnes budeme pokračovat s tvorbou jejich administrace v redakčním systému postaveném na JavaScript frameworku AngularJS.

Externí JS knihovny

Jelikož AngularJS je poměrně robustní framework, který přebírá kontrolu nad většinou javascriptového dění na celé stránce, není úplně lehké ho propojit s některými knihovnami. Naštěstí pro ty populární existují již připravené moduly, které vše usnadní. Příkladem je třeba TinyMCE, které jsem se rozhodl použít pro pohodlnou editaci HTML obsahu článků.

assets/lib/js/an­gular-ui-tinymce.min.js

Pro práci s ním je třeba kromě samotné knihovny vložit do projektu i modul - AngularUI wrapper for TinyMCE, který slouží jako obal pro využití této knihovny v prostředí AngularJS. Tento modul si tedy stáhněte a vložte do složky pro externí knihovny naší aplikace.

app/cms.module.js

Dále ho ještě nezapomeneme klasicky zavést jako modul naší aplikace:

'use strict';

// Deklarace modulu aplikace.
var app = angular.module('cms', ['ngRoute', 'ngResource', 'ngMockE2E', 'ngSanitize', 'ngMessages', 'ui.tinymce']);

Kontrolery

Jelikož modelovou vrstvu v podobě simulovaného nebo vlastního plnohodnotného API máme již nachystanou z minulé lekce, začneme rovnou od kontrolerů.

app/controller­s/article-list.controller.js

V AngularJS máme standardně k jednomu kontroleru jednu šablonu, kontroler tedy většinou reprezentuje jednu samostatnou stránku. Proto si pro výpis seznamu článků, jako samostatnou stránku, vytvoříme vlastní šablonu a kontroler, který bude vypadat následovně:

'use strict';

/** Zpracovává vykreslování seznamu článků. */
app.controller('ArticleListController', function ($rootScope, $scope, Articles) {
        $rootScope.title = 'Výpis článků';
        $rootScope.description = 'Výpis všech článků.';

        this.articles = Articles.query();

        /**
         * Odstraní článek.
         * @param {int} index - Index článku v poli článků.
         */
        this.remove = function (index) {
                // Odstraní článek pomocí API.
                Articles.delete({url: this.articles[index].url}, (function () {
                        // Odstraní článek z aktuálního seznamu článků.
                        this.articles.splice(index, 1);
                }).bind(this), function (error) {
                        console.error(error);
                });
        };
});

Zde se toho moc nového neudálo, pouze vidíme způsob načtení článku z API a definici metody kontroleru pro jejich smazání, jak z lokálně načtených dat, tak opět i z API.

app/controller­s/article-editor.contro­ller.js

Další na řadě bude kontroler reprezentující stránku editoru článků:

'use strict';

/** Zpracovává vykreslování editoru článků. */
app.controller('ArticleEditorController', function ($routeParams, $rootScope, $scope, $location, Articles) {
        $rootScope.title = 'Editor';
        $rootScope.description = 'Editor článků.';

        // Počáteční hodnota / základ pro nový článek.
        $scope.article = {
                url: '',
                title: '',
                content: '',
                description: ''
        };

        var url = $routeParams.url; // Získání URL editovaného článku.

        // Načtení dat editovaného článku z API, pokud byla zadána jeho URL.
        if (url) Articles.get({url: url}, function (article) {
                $scope.article = article;
        }, function (error) {
                console.error(error);
        });

        // Nastavení pro TinyMCE.
        this.tinymceOptions = {
                selector: '#editorForm-content',
                plugins: [
                        'advlist autolink lists link image charmap print preview anchor',
                        'searchreplace visualblocks code fullscreen',
                        'insertdatetime media table contextmenu paste'
                ],
                toolbar: 'insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image',
                entities: '160,nbsp',
                entity_encoding: 'raw'
        };

        /** Uloží článek. */
        this.save = function () {
                Articles.save($scope.article, function (article, headers) {
                        $location.path(headers('Location')); // Přesměrování na zobrazení článku.
                }, function (error) {
                        console.error(error);
                });
        };
});

Zde si nejdříve připravíme datovou kostru pro nový článek, kterou přes API doplníme daty článku existujícího, v případě že se jedná o editaci. To poznáme jednoduše podle zadané URL adresy. Následuje místní nastavení pro TinyMCE a na konci zde pak ještě přidáváme metodu pro uložení článku do API.

Šablony

Nyní se podíváme na šablony k jednotlivým kontrolerům.

app/templates/ar­ticle-list.html

Začneme šablonou pro výpis článků:

<table>
        <tr ng-repeat="(index, article) in articleList.articles">
                <td>
                        <h2><a href="#!{{article.url}}">{{article.title}}</a></h2>
                        {{article.description}}
                        <br/>
                        <a href="#!editor/{{article.url}}">Editovat</a>
                        <a href ng-click="articleList.remove(index)">Odstranit</a>
                </td>
        </tr>
</table>

Zde jsou hned dvě novinky. Za prvé je vidět práce s polem dat v rámci šablony, kde AngularJS vezme v cyklu ng-repeat jednotlivé články a ke každému vytvoří příslušný řádek (<tr>) HTML tabulky. Za druhé je zde ukázka volání metody kontroleru pro smazání článku při kliknutí na odkaz.

app/templates/ar­ticle-editor.html

Nyní šablona pro editor článků:

<!-- AngularJS formulář s mapováním dat i vlastní validací (výchozí validace v prohlížeči vypnuta). -->
<form name="editorForm" ng-submit="articleEditor.save()" novalidate>
        <!-- TITLE -->
        <div class="form-group">
                <label for="editorForm-title">Titulek</label>
                <input id="editorForm-title" type="text" name="title" ng-model="article.title" required>

                <!-- Definice chybových zpráv. -->
                <div ng-messages="editorForm.title.$error" ng-show="editorForm.title.$touched">
                        <p ng-message="required">Titulek článku nemůže být prázdný!</p>
                </div>
        </div>

        <!-- URL -->
        <div class="form-group">
                <label for="editorForm-url">URL</label>
                <input id="editorForm-url" type="text" name="url" ng-model="article.url" required>
                <div ng-messages="editorForm.url.$error" ng-show="editorForm.url.$touched">
                        <p ng-message="required">URL článku nemůže být prázdná!</p>
                </div>
        </div>

        <!-- DESCRIPTION -->
        <div class="form-group">
                <label for="editorForm-description">Popisek</label>
                <input id="editorForm-description" type="text" name="description" ng-model="article.description" required>
                <div ng-messages="editorForm.description.$error" ng-show="editorForm.description.$touched">
                        <p ng-message="required">Popisek článku nemůže být prázdný!</p>
                </div>
        </div>

        <!-- CONTENT -->
                <div class="form-group">
                        <label for="editorForm-content">Obsah</label>
                        <textarea id="editorForm-content" name="content" ui-tinymce="articleEditor.tinymceOptions" ng-model="article.content" required></textarea>
                        <div ng-messages="editorForm.content.$error" ng-show="editorForm.content.$touched">
                                <p ng-message="required">Obsah článku nemůže být prázdný!</p>
                </div>
        </div>

        <!-- SUBMIT BUTTON -->
        <button type="submit" ng-disabled="editorForm.$invalid">Uložit článek</button>
</form>

Formulář v AngularJS jsme již viděli v prvním projektu u kalkulačky, ovšem zde je rozšířen o další validační prvky a ukazuje se zde opravdová síla frameworku.

U každého elementu formuláře si můžete povšimnout způsobu definice vlastních validačních pravidel a chybových zpráv, které se zobrazí při jejich porušení. Také formulář nelze odeslat, dokud není celý validní.

Pole pro obsah zde má navíc ještě direktivu pro aktivaci již výše zmíněného TinyMCE a předání jeho příslušné konfigurace.

index.html

Lekci zakončíme klasicky úpravou a rozšířením hlavního souboru naší aplikace. Nebudu sem už vypisovat znovu celou šablonu, ale pouze změny:

...
<nav>
        <ul>
                <li><a href="#!uvod">Úvod</a></li>
                <li><a href="#!seznam-clanku">Seznam článků</a></li>
                <li><a href>Kontakt</a></li>
        </ul>
</nav>
...
<!-- TinyMCE a jeho integrace pro AngularJS -->
<script type="text/javascript" src="//tinymce.cachefly.net/4.0/tinymce.min.js"></script>
<script type="text/javascript" src="assets/lib/js/angular-ui-tinymce.min.js"></script>
...
<!-- Kontrolery. -->
<script src="app/controllers/article.controller.js"></script>
<script src="app/controllers/article-list.controller.js"></script>
<script src="app/controllers/article-editor.controller.js"></script>
...

Routování

app/cms.routes.js

Na závěr přidáme nová routovací pravidla:

'use strict';

/** Definice routovacích pravidel naší aplikace. */
app.config(function ($routeProvider) {
        var templatePath = 'app/templates/';

        $routeProvider
                .when('/seznam-clanku', {
                        templateUrl: templatePath + 'article-list.html',
                        controller: 'ArticleListController',
                        controllerAs: 'articleList'
                })
                .when('/editor/:url?', {
                        templateUrl: templatePath + 'article-editor.html',
                        controller: 'ArticleEditorController',
                        controllerAs: 'articleEditor'
                })
                .when('/:url?', {
                        templateUrl: templatePath + 'article.html',
                        controller: 'ArticleController',
                        controllerAs: 'article'
                })
                .otherwise({
                        redirectTo: '/'
                });
});

Jak vidíte, zde se nám naše nové kontrolery a šablony krásně propojí dohromady pod URL adresami, které jsem se rozhodl zachovat v češtině.

Nyní se již můžete podívat na výsledek, zkusit si vypsat seznam článků a klidně je i nějak editovat. :)

V příští lekci, Jednoduchý redakční systém v AngularJS - Kontaktní formulář, si přidáme ještě kontaktní formulář a administraci článků v našem AngularJS redakčním systému dokončíme.


 

Stáhnout

Staženo 15x (26.41 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript

 

 

Článek pro vás napsal Jindřich Máca
Avatar
Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!
Autor se věnuje převážně webovým technologiím, ale má velkou zálibu ve všem vědeckém, nejen ze světa IT. :-)
Aktivity (2)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!