タケユー・ウェブ日報

Ruby on Rails や Flutter といったWeb・モバイルアプリ技術を武器にお客様のビジネス立ち上げを支援する、タケユー・ウェブ株式会社の技術ブログです。

AngularJS + MovableType Data API でインクリメンタル検索してみた

Movable Type 6の新機能「Data API」。
藤本さんをはじめ皆様がすでにいろいろ試されていますが、僕も少し触ったのでメモ。

プログラマな人には好感触ですが、デザイナーさんにはいまいちピンとこないのではないでしょうか。
Data API自体はこれまでとは違ったニーズの掘り起こしを狙ってる気がしますが、あえてこれまでのようなWebサイト制作で役立ちそうなネタを書くことにします。

やったこと


http://mt.takeyu-web.com/data_api_test/angularjs-data-api.html


と、こんな具合に、JSON APIが提供されたことで、JSONを書き出すテンプレートを作成してダイナミックパブリッシングで・・・とか、検索用PHPを作って・・・とか、面倒なことなしに検索機能を実装できます。
また Data APIは記事以外にもカテゴリなどいろいろ簡単に検索できます。

もっともこれは Data API のほんの一部を利用した例であり、本来はもっといろいろな機能があるので、「これがData APIだ!」というわけではない点にご留意ください。

ソース

HTML

<!doctype html>
<html lang="ja" ng-app="DataAPIExample">
  <head>
    <meta charset="utf-8">
    <title>AngularJS + Data API でインクリメンタル検索するテスト</title>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular-resource.min.js"></script>
    <script src="https://raw.github.com/grevory/angular-local-storage/master/localStorageModule.js"></script>
    <script src="entries-controller.js"></script>
  </head>
  <body>

    <h1>AngularJS + Data API でインクリメンタル検索するテスト</h1>
    <div ng-controller="EntriesController">キーワード:<input ng-model="query" ng-keyup="doSearch()" type="search" />
      <div ng-show="query">
        <h2>'{{query}}'での検索結果</h2>
        <p ng-show="loading">読み込み中です</p>
        <p ng-hide="loading">
          <span ng-show="totalResults > 0">{{totalResults}}件見つかりました。</span>
          <span ng-hide="totalResults > 0">見つかりませんでした。</span>
        </p>
        <ul ng-repeat="item in items">
          <li><a href="{{item.permalink}}">{{item.title}}</a><br /><span ng-bind-html-unsafe="item.excerpt"></span></li>
        </ul>
      </div>
      <div ng-hide="query">
        <p>キーワードを入力して下さい。</p>
      </div>
    </div>
  </body>
</html>

JavaScript

window.App = angular.module('DataAPIExample', ['ngResource', 'LocalStorageModule']);
angularLocalStorage.constant('prefix', 'DataAPIExample');
App.controller(
    'EntriesController',
    ['$scope', '$http', '$q', 'localStorageService', function($scope, $http, $q, localStorageService){
        $scope.query = localStorageService.get('query')
        $scope.loading = false;
        $scope.items = [];
        $scope.totalResults = null;
        $scope.canceler = null;
        $scope.doSearch = function(){
            if ($scope.canceler) {
                $scope.canceler.resolve();
                $scope.canceler = null;
            }
            $scope.canceler = $q.defer();
            var url = 'http://mt.takeyu-web.com/mt/mt-data-api.cgi/v1/sites/34/entries';
            if ($scope.query) {
                url = url + '?search=' + encodeURIComponent($scope.query);
            }
            $scope.currentRequest = $http.get(url, {timeout: $scope.canceler.promise}).success(function(json, status){
                $scope.loading = false;
                $scope.totalResults = json.totalResults;
                $scope.items = json.items;
            });
            $scope.loading = true;
            localStorageService.add('query', $scope.query);
        };
        $scope.doSearch();
    }]
);