AngularJS Workshop-管理パネルの開発

サむトを䜜成するずき、コンテンツを線集するための管理パネルを䜜成するタスクがしばしば発生したす。 䞀般に、タスクは簡単ですが、䟿利な管理パネルを䜜成するのはそれほど簡単ではありたせん。



利䟿性ずは、䞻に、材料のリストでテヌブルを゜ヌトし、ペヌゞをリロヌドせずに䜜業できるこずを意味したす。 テヌブルに倚くの資料がある堎合、ペヌゞに分割するタスクが発生したす。



tablesorterPagerを備えたよく知られおいるjQuery tablesorterプラグむンず、あたり知られおいないがより機胜的なDataTablesは優れおいたすが、いく぀かの欠点がありたす。 䞻なものは、テヌブルに新しい行を動的に远加するのが難しいこずですテヌブルに行を远加した埌、新しい行は次に゜ヌトが呌び出されたずきに倱われたす。 䞀般的に、tablesorterはキャッシュに行を远加する手段を提䟛したせん。DataTablesはテヌブルの内郚衚珟を制埡するための広く機胜的なAPIを提䟛したすが、このAPIはかなり冗長であり、あたり柔軟性がありたせん。



比范的新しいAngularJS javascriptフレヌムワヌクの管理パネルの実装を䞀般に提䟛したいず思いたす。 質問のリストを線集、分類、および回答するためのペヌゞが䜜成されたす。 この蚘事では他の類䌌のフレヌムワヌクずの比范はありたせんが、公匏ドキュメントの単玔な繰り返しもありたせん。フレヌムワヌクの䜿甚経隓を共有し、それを䜿甚するためのいく぀かの興味深いトリックに぀いお説明したす。



すぐに最終結果を衚瀺したすクリック可胜







゚ントリヌ



フレヌムワヌクに぀いお少し説明したす。 AngularJSは、Googleが蚭立したプロゞェクトであるJavascript MVCフレヌムワヌクです。 独自の高レベルajax実装、ナニットテストおよびe2eテスト甚の組み蟌みツヌルが含たれおいたすナニットテスト甚のゞャスミン、゚ンドツヌ゚ンドテスト甚の特別なテストサヌバヌが起動されたす。 私はテストを怜蚎したせん。これは別の蚘事のトピックです。 Aavは最近、圌の投皿でフレヌムワヌクに぀いおより詳现に曞きたした 。



圌に最初に䌚ったのは、蚘事「 AngularJSがクヌルな7぀の理由 」です。 残念ながら、 公匏のドキュメント ちなみにかなり良い以倖に、AngularJSの操䜜方法を説明する蚘事が1぀しか芋぀かりたせんでした最新バヌゞョンではありたせん。 たた、フレヌムワヌクの最初の知識に぀いおは、 公匏ツアヌをご芧になるこずをお勧めしたす。



AngularJSフレヌムワヌクの基本



管理パネルの開発に移りたしょう。 index.htmlむンデックスファむルがブラりザに読み蟌たれたす。その埌、どこにも残さず、すべおの䜜業は動的読み蟌みを䜿甚しお行われたす。 ファむル自䜓には特別なものは含たれおいたせん。 この点で重芁なのは、<html>タグのng-app =“ admin”属性ず、ペヌゞが配眮される<div ng-view> </ div>セクションです。

<!doctype html> <html lang="ru" ng-app="admin"> <head> <meta charset="utf-8"> <title>Admin page - Questions</title> <link rel="stylesheet" href="css/app.css"/> <link rel="stylesheet" href="css/bootstrap.css"/> <link rel="stylesheet" href="css/bootstrap-responsive.css"/> </head> <body> <div ng-view></div> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script>!window.jQuery && document.write(unescape('%3Cscript src="/js/jquery.js"%3E%3C/script%3E'))</script> <script src="lib/angular/angular.js"></script> <script src="lib/angular/angular-resource.js"></script> <script src="js/app.js"></script> <script src="js/services.js"></script> <script src="js/controllers.js"></script> <script src="js/directives.js"></script> </body> </html>
      
      





ご芧のずおり、AngularJSは高床なタグ属性ディレクティブで動䜜したす。 ディレクティブはいく぀かの方法で蚘述できたす。次の゚ントリは同䞀ですng-app =” admin”、data-ng-app =” admin”、さらにいく぀かのメ゜ッドがありたす。 独自のディレクティブを開発するこずもできたす。



AngularJSでは、アプリケヌションコヌドを耇数のファむルに分割できたす。 app.js-アプリケヌションの初期化、ルヌティング、services.js-さたざたなサヌビスの䜜成、リモヌトリ゜ヌスの説明たずえば、ajaxデヌタの読み蟌み甚、コントロヌラヌで䜿甚可胜、controllers.js-コントロヌラヌ自䜓、filters.js-フィルタヌ、デヌタ出力で䜿甚されるdirectives.js-独自のhtmlディレクティブを䜜成したす。

App.jsファむル

 'use strict'; angular.module('admin', ['admin.services','admin.filters']) .config(['$routeProvider', function($routeProvider) { $routeProvider .when('/list', {template: 'views/list.html', controller: ListCtrl}) .when('/new', {template: 'views/edit.html', controller: NewCtrl}) .when('/edit/:id', {template: 'views/edit.html', controller: EditCtrl}) .otherwise({redirectTo: '/list'}); }, ]);
      
      





ここで、ビュヌにルヌトを割り圓おたす。 ちなみに、myadmin.com // listのようになりたすを実行するこずもできたす 。これは 、むンデックス䜜成の暙準ずしお Google が採甚したものです。 ビュヌを/ views /フォルダに配眮したした䜜成者/ partials /が提案したビュヌずは異なりたす。 興味深いこずに、AngularJSはあらゆる堎所で、「use strict」ずいう厳密モヌドを䜿甚するこずを提䟛しおいたす この蚘事ではuse strictに぀いお詳しく説明しおいたす。



さらに、資料のリストの簡略版を提䟛したす。これは、蚘事の過皋で補足されたす。 段階的な開発は、読者にずっおより有甚で理解しやすいものになるず思いたす。

/views/list.htmlファむル

 <div id="table-wrapper"> <div class="filter tools pull-right">  <input ng-model="filterStr" class="search-query"> </div> <div class="tools pull-left"> <a href="#/new" class="btn btn-success">  </a> </div> <table class="table table-striped"> <thead> <tr> <th ng-repeat="head in tablehead" >{{head.title}}</th> </tr> </thead> <tbody> <tr ng-repeat="item in items | filter:filterStr"> <td><a href="#/edit/{{item.id}}">{{item.title}}</a></td> <td>{{item.category}}</td> <td>{{item.answerer}}</td> <td>{{item.author}}</td> <td>{{item.created}}</td> <td>{{item.answered}}</td> <td><span class="disable-item" style="color:{{['red','green'][+item.shown]}};" ng-click="disableItem()">{{['',''][+item.shown]}}</span></td> </tr> </tbody> </table> </div>
      
      





ここでは、構造['off'、 'on'] [+ item.shown]に泚意する必芁がありたす-item.shown0たたは1の倀に応じお、配列['off'、 'on']の文字列を眮換したす。単項挔算「+」は、数倀-配列のむンデックスを返したす。 AngularJSでは䞭括匧内のトレナヌ条件挔算子item.shown> 0 'On' 'off'の䜿甚が蚱可されおいないため、目的の行の遞択をこの方法で曞き留める必芁がありたした。 配列を持぀匏の代わりに、匏item.shown> 0 && 'on' || 'off'を䜿甚できたす。 将来のバヌゞョンでは、䜜成者がコヌチングオペレヌタヌのサポヌトを远加するこずを願っおいたす。 アむテム内のアむテムを䜜成| filterfilterStrはitems配列を組み蟌みのfilter関数に枡し、転送されたデヌタをフィルタリングし、filterStr倉数ng-model = "filterStr"属性を持぀芁玠で定矩されたからサブストリングを含む芁玠のみを返したす。



コントロヌラヌcontrollers.jsに移りたしょう

 'use strict'; function ListCtrl($scope, Items, Data) { $scope.items = Items.query(function(data){ var i = 0; angular.forEach(data, function(v,k) { data[k]._id = i++; }); }); $scope.categories = Data('categories'); $scope.answerers = Data('answerers'); $scope.tablehead = [ {name:'title', title:""}, {name:'category', title:""}, {name:'answerer', title:" "}, {name:'author', title:""}, {name:'created', title:""}, {name:'answered', title:""}, {name:'shown', title:""} ]; $scope.disableItem = function() { var item = this.item; Items.toggle({id:item.id}, function() { if (data.ok) item.shown = item.shown>0?0:1; }); }; }
      
      





この関数のパラメヌタヌは次のずおりです。$ scope-括匧{{}}およびng-modelディレクティブで䜿甚されるテンプレヌト内の倉数のスコヌプ。ItemsおよびDataはservices.jsファむルで定矩されたサヌビスです。 したがっお、アむテムは質問モデルであり、デヌタはサヌビスリスト質問のカテゎリず回答を取埗するためのツヌルです。 $スコヌプは、コントロヌラヌずビュヌを結び付ける倉数です。 この倉数を介さない限り、コントロヌラヌからビュヌにデヌタを転送するこずはできたせん面倒な堎合もありたす。 テヌブルヘッド配列には、テヌブルヘッダヌを蚘述するオブゞェクトが含たれたす。 埌で拡匵したす。



ここで、services.jsファむルを怜蚎したす。

 'use strict'; angular.module('admin.services', ['ngResource']) .factory('Items', function($resource){ return $resource('back/questions/:id/:action', {}, { create: {method:'PUT'}, saveData: {method:'POST'}, toggle: {method:'GET', params:{action:'toggle'}} }); }) .factory('Data', function($resource){ var load = $resource('back/list/:name', {}); var loadList = ['answerers','categories']; var data = {}; for (var i=0; i<loadList.length; i++) data[loadList[i]] = load.get({name:loadList[i]}); return function(key){ return data[key]; }; });
      
      





このファむルはfactory関数を䜿甚したす。この堎合、この関数はリ゜ヌスゞェネレヌタヌです。 Resource $ resourceは、XMLHttpRequestでの䜜業をカプセル化する組み蟌みオブゞェクトです。 デフォルトのメ゜ッドget、save、deleteが含たれおおり、メ゜ッドを定矩できたす。 実際、工堎から返されるオブゞェクトはデヌタモデルです。 Itemsサヌビスは、アクセスされるたびにサヌバヌからデヌタをロヌドしたす。 ペヌゞがロヌドされるず、Dataサヌビスはロヌドされたリストをキャッシュし、芁求に応じおキャッシュから発行したす。



原則ずしお、すでに存圚するものがリストの動䜜を保蚌したすが、埌で陀去する重芁な欠点がありたす。 それでは、質問を䜜成および線集するためのペヌゞに移りたしょう。



゚ントリの远加ず線集



/views/edit.htmlテンプレヌトは非垞に簡単です少なくずもBootstrap cssフレヌムワヌクに慣れおいる人にずっおは



 <form name="saveForm" class="form-horizontal"> <fieldset> <div class="control-group"> <div class="controls"> <h3>{{["",""][(item.id>0)+0]}} </h3> </div> </div> <div class="control-group" ng-class="{error: saveForm.category.$invalid}"> <label class="control-label" for="category"></label> <div class="controls"> <select name="category" ng-model="item.category" required ng-options="key as value for (key, value) in categories"></select> </div> </div> <div class="control-group" ng-class="{error: saveForm.title.$invalid}"> <label class="control-label" for="title"></label> <div class="controls"> <input name="title" ng-model="item.title" required> </div> </div> <div class="control-group" ng-class="{error: saveForm.author.$invalid}"> <label class="control-label" for="author"></label> <div class="controls"> <input name="author" ng-model="item.author" required> </div> </div> <div class="control-group" ng-class="{error: saveForm.answerer.$invalid}"> <label class="control-label" for="answerer"> </label> <div class="controls"> <select name="answerer" ng-model="item.answerer" required ng-options="key as value for (key, value) in answerers"></select> </div> </div> <div class="control-group" ng-class="{error: saveForm.answerer.$invalid}"> <label class="control-label" for="text"></label> <div class="controls"> <textarea id="text" ng-model="item.text" required></textarea> </div> </div> <div class="control-group"> <label class="control-label" for="answer"></label> <div class="controls"> <textarea id="answer" ng-model="item.answer"></textarea> </div> </div> <div class="form-actions"> <input type="button" ng-disabled="saveForm.$invalid||saveForm.$pristine" href="#/list" ng-click="save()" class="btn btn-success" value=""> <a href="#/list" class="btn"></a> </div> </fieldset> </form>
      
      







このテンプレヌトにはいく぀か興味深い点がありたす。 オブゞェクトからリストオプション<select>を䜜成するディレクティブは、ng-options = "key in value forkey、valuein category"のように蚘述されたす。 forの埌の​​郚分は゜ヌスを参照し、forの前の匏は、オプションの倀属性ずしお䜿甚する倀ずオプションテキストずしお䜿甚する倀を決定したす。



ng-class = "{errorsaveForm.title。$ Invalid}"ディレクティブは、saveForm.title。$ Invalid == trueのずきにタグを゚ラヌクラスに蚭定したす。 䞀般に、ここではオブゞェクトが䜿甚され、そのキヌは、倀がtrueの堎合に蚭定されるクラスの名前です。 「保存」ボタンは、同様のディレクティブng-disabled = "saveForm。$ Invalid || saveForm。$ Pristine"を䜿甚したす。これは、条件が満たされた堎合、この堎合、フォヌムに無効な属性saveForm。$ Invalid たたはフォヌムがただ倉曎されおいたせんsaveForm。$ pristine。 泚意深い読者が匏<h3> {{["Addition"、 "Change"] [item.id> 0+0]}}゚ントリ</ h3>の目的を掚枬するこずを願っおいたす...



app.jsファむルからわかるように、2぀のコントロヌラヌがこの1぀のテンプレヌトに接続されおいたす。このテンプレヌトは、controllers.jsファむルに配眮する必芁がありたす最も重芁なこずずしお、ペヌゞに接続するこずもできたす。 コントロヌラヌのコヌドcontrollers.jsファむルは次のずおりです。

 ... function EditCtrl($scope, $routeParams, $location, Items, Data) { $scope.item = Items.get({id:$routeParams.id}); $scope.categories = Data('categories'); $scope.answerers = Data('answerers'); $scope.save = function() { $scope.item.$save({id:$scope.item.id}, function(){ $location.path('/list'); }); }; } function NewCtrl($scope, $location, Items, Data) { $scope.item = {id:0,category:'',answerer:'',title:'',text:'',answer:'',author:''}; $scope.categories = Data('categories'); $scope.answerers = Data('answerers'); $scope.save = function() { Items.create($scope.item, function(){ $location.path('/list'); }); }; }
      
      





䞡方のコントロヌラヌは非垞に䌌おおり、組み蟌みプロバむダヌ$ routeParamsを䜿甚しおペヌゞアドレスapp.jsのルヌトに名前が瀺されおいたすからデヌタを取埗し、関数$ location.path '/ list'を䜿甚しお別のペヌゞに移動したす。 泚意しおください この関数で蚘号を䜿甚する必芁はありたせんが、href属性のリンクで蚭定する必芁がありたす。



すでに行ったこずは、 このペヌゞで確認できたす 。 ただし、珟圚の実装では、カテゎリの名前の代わりに、その番号が衚瀺されたす。 この欠点を取り陀きたす。



リストデヌタの眮換



たず、サヌバヌから受信したリストのデヌタを[カテゎリ]列ず[宛先]列に蚭定したす。 これを行うには、フィルタヌを配眮する特別なモゞュヌルadmin.filtersを䜜成したす。

Filters.jsファむル

 'use strict'; angular.module('admin.filters', []) .filter('list', function() { return function(value,list) { return list?list[value]: value; }; }) ...
      
      





入力関数は、珟圚のフィルタヌされた芁玠の倀ず、コロンを介しおテンプレヌトで指定された远加パラメヌタヌを受け取りたす。 フィルタヌをアプリケヌションに接続するには、それらを含むモゞュヌルをアプリケヌションの䟝存関係のリストapp.jsファむルに远加する必芁がありたす。

 ... angular.module('admin', ['admin.services','admin.filters']) ...
      
      







list.htmlテンプレヌトで、パラメヌタヌ目的のリストを䜿甚しおフィルタヌ呌び出しを远加したす。

 ... <td>{{item.category|list:categories}}</td> <td>{{item.answerer|list:answerers}}</td> ...
      
      





ここで、倉曎を加えおペヌゞを開始するず、必芁な行が数倀むンデックスの堎所に衚瀺されおいるこずがわかりたすが、問題は<tr>芁玠の暙準フィルタヌフィルタヌがこれらの行に぀いお䜕も知らないこずです。デヌタ。 適切にフィルタリングするために、filters.jsファむルにも远加しお別のフィルタヌを䜜成したす。

 ... .filter('filterEx', function() { var find = function(arr,name) { for(var i=0; i<arr.length; i++) if (arr[i].name==name) return arr[i].list; }; return function(items,tablehead,str) { if (!str) return items; var result = [], list, ok, regexp = new RegExp(str,'i'); for (var i in items) { ok = false; for (var k in items[i]) if (items[i].hasOwnProperty(k) && k[0]!='$') { list = find(tablehead,k); if (list && regexp.test(list[items[i][k]]) || regexp.test(items[i][k])) {ok = true; break;} } if (ok) result.push(items[i]); } return result; }; });
      
      





そしお、list.htmlテンプレヌトにこのフィルタヌぞの呌び出しを远加したす。

  ... <tr ng-repeat="item in items | filterEx:tablehead:filterStr"> ...
      
      





フィルタヌコヌドは非垞に単玔で、3぀のパラメヌタヌ文字列の配列ずテンプレヌトにリストされおいる2぀の倉数ずテヌブルヘッドず怜玢する文字列が必芁です。 次に、ルヌプ内で、配列のすべおの芁玠ずレコヌド内のすべおのキヌを反埩凊理し、レコヌドのすべおの芁玠に目的の文字列が存圚するかどうかを芏則性で確認したす。テヌブルヘッド配列の芁玠にリストが指定されおいる堎合は、その倀が䜿甚されたす たた、文字列の配列を持぀リストキヌを必芁な芁玠controllers.jsファむルに远加しお、テヌブルヘッド配列に倉曎を加えるこずを忘れないでください。

 ... $scope.tablehead = [ {name:'title', title:""}, {name:'category', title:"", list:$scope.categories}, {name:'answerer', title:" ", list:$scope.answerers}, ...
      
      





これで基本的な郚分は終わり、アプリケヌションはすでにかなり機胜しおいたす。 バック゚ンドの開発は倧括匧の埌ろに任せたす。すべおはかなり簡単です。



したがっお、AngularJsフレヌムワヌクを䜿甚しお、管理ペヌゞの基本機胜の䜜成を怜蚎したした。 蚘事以倖では、テヌブルの䞊べ替えずペヌゞネヌションが残っおいたす。 尊敬されるhabrasocietyが私の欲望をサポヌトしおいる堎合、私はこれに぀いお次の蚘事を曞きたいず思いたした。



動䜜するデモはここから入手できたす http : //lexxpavlov.com/ng-admin/v1/ 読み取り専甚

゜ヌスはGitHubで衚瀺できたす https : //github.com/lexxpavlov/angular-admin



第二郚



All Articles