【Angularjs】 ng-repeatのフィルター・ソート

フィルター「limitTo」

まずは表示数を制御する「limitTo」 ★の箇所がフィルターを利用している箇所です。

limitTo:3で、表示する件数を最大3件としています。

<table>
  <tr>
    <th>Part</th><th>Name</th><th>Title</th>
  </tr>
  <tr ng-repeat="jojo in jojos | limitTo:3"> ★
    <td>{{jojo.part}}</td>
    <td>{{jojo.name}}</td>
    <td>{{jojo.title}}</td>
  </tr>
</table>

並び替え「orderBy」

表示順を制御する「orderBy」 ★の箇所がソートを利用している箇所です。 「orderBy」で指定した配列名を主キーに並び替え表示されます。

下記の例では、orderBy:'title'で、名前順に昇順で表示します。

<table>
  <tr>
    <th>Part</th><th>Name</th><th>Title</th>
  </tr>
  <tr ng-repeat="jojo in jojos | orderBy:'title'">
    <td>{{jojo.part}}</td>
    <td>{{jojo.name}}</td>
    <td>{{jojo.title}}</td>
  </tr>
</table>

また、下記のように配列名にマイナスを加えると降順になります。

<tr ng-repeat="jojo in jojos | orderBy:'-part'">

複合フィルター

下記のようにフィルターは複数指定することもできます。

<tr ng-repeat="jojo in jojos | orderBy:'title' | limitTo:2">

【AngularJS】コントローラーの変更がビューに反映されない時は$scope.apply();

jQueryのイベントを使ってモデルの値を変更した場合など、ビューに変更が伝わらない場合がある。

具体的には以下のような場合

HTML

<div id="images">
    <div ng-repeat="picture in pictures">
      <div class="img">
        <a target="_blank" href="">
          <img src="{{picture.img_url}}">
        </a>
      </div>
    </div>
</div>
.controller('PictureDetailController', function($scope, $http) {
  $(function() {
      //★初回クリック(jQueryのイベントを使用)
      $('#images').one('click', function() {
          $scope.pictures.push(picture);
      });
  });
}

このような場合は、手動でモデルの変更をビューへ伝える必要がある。 この時に使うのがapply()だ。上記の例を、applyを使ってモデルの変更をビューに伝えるよう修正する。

.controller('PictureDetailController', function($scope, $http) {
  $(function() {
      //初回クリック(jQueryのイベントを使用)
      $('#images').one('click', function() {
          $scope.pictures.push(picture);
          $scope.apply(); ★モデルの変更をビューに伝える
      });
  });
}

これで、ビューにモデルの変更が通知されて、DOMが変化している。

Javascriptを使って5分でできるタブ切り替え

タイトルの通り、手軽にタブ切り替えを実装します。 JavascriptCSSを利用します。

まずはHTML

<!-- トグルボタン -->
<div id="tab">
  <div>
    <input type="radio" class="selected" checked>
    <div>Tab A</div>
  </div>
  <div>
    <input type="radio">
    <div>Tab B</div>
  </div>
</div>

<div class="content_wrap">
コンテンツ1
</div>
<div class="cotent_wrap nodis">
コンテンツ2
</div>

次にJavaScript

$(function() {
    $("#tab input").click(function() {
        var num = $("#tab input").index(this);
        $(".content_wrap").addClass('nodisp');
        $(".content_wrap").eq(num).removeClass('nodisp');
        $("#tab input").removeClass('selected');
        $(this).addClass('selected')
    });
});

ラジオボタンが押されると、nodispクラスが切り替わります。

最後にCSS

.selected {
  background: yellow;
}

.nodisp {
  display: none;
}

.selectedでは、選択されているタブの背景色をyellowに指定しています。 .nodispを非選択状態のcontent_wrapperに付加しています。

Sublime TextでCSSのリアルタイムプレビュー

Sublimeではリアルタイムプレビューがないものだと思い込んで諦めていたところ、ふと見つけたので使ってみたら便利さに衝撃を受けたのでメモ。 ざっくりと使い方をまとめておきます。

導入方法

  1. Sublime Textにプラグイン「LiveStyle」をインストール
  2. Chrome拡張機能Emmet LiveStyle拡張」を追加
  3. リアルタイムプレビューしたいページで、Emmet LiveStyleを有効にして、CSSを編集※

chromeのDeveloper Toolsを編集すると、Sublimeで開いているCSSに適用されるし、Sublimeで開いているCSSファイルを編集すると、ブラウザで開いているページがリアルタイムで変更される。

詳しい使い方は以下

livestyle.io

EmmetLiveStyleでSublimeText3でリアルタイムプレビューが出来て超便利! | Taka's Life

タブパネルでGoogle Mapを表示させる

タブパネルでGoogle Mapを表示させる際、最初に表示されるページにGoogle Mapを設置していれば問題ないが、最初に表示されないタブ内に設置していた場合、initialize処理が別途必要になるので、メモ。

例に2枚タブ構成のスクリプトを示す。

      <div id="tabs" class="tabs">
        <nav>
          <ul>
            <li><a href="#section-1"><i class="fa fa-list-ul">タブ1</i></a></li>
            <li><a href="#section-2" ><i class="fa fa-map-marker">タブ2</i></a></li>
          </ul>
        </nav>
        <div class="content">
          <!-- Time Line view -->
          <section id="section-1">
            <div class="mediabox">
              <h3>最初に表示されるタブ</h3>
            </div>
          </section>

          <section id="section-2">
            <div class="mediabox">
              <h3>Google Mapエリア</h3>
              <div id="map_canvas" style="width:500px; height:300px"</div>
            </div>
          </section>

        </div><!-- /content -->

いつもどおりのGoogle Mapのinitialize処理は以下。

    <script>
      //initialize google map
      function initialize() {
        var latlng = new google.maps.LatLng(35.539001,134.228468);
        var opts = {
          zoom: 13,
          center: latlng,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        var map = new google.maps.Map(document.getElementById("map_canvas"), opts);
      }
      google.maps.event.addDomListener(window, "load", initialize);
    </script>

今回は、タブ2にGoogle Mapが埋め込まれ、初回ページロード時にinitializeが走らない。 そこで、以下のようにして、初回タブ2クリック時にのみinitializeが実行されるようにスクリプトを追加。

      $(function(){
        $("#map-tab").one(
          'click',
          function(){
            initialize();
          }
        );
      });

これで、初回表示画面以外のタブにGoogle Mapを設置した場合でも、地図が表示されるようになる。

ruby on railsでwheneverでrakeタスクを実行させようとすると”/bin/bash: bundle: コマンドが見つかりません”

railsのタスクスケジューリングgem「whenever」でrakeタスクを登録してログを見てみると、以下のようなエラーが出た。

/bin/bash: bundle: コマンドが見つかりません

どうやら、パスをschedule.rbに登録しておく必要がある。

以下の記述をconfig/schedule.rbの上の方に追加

env :PATH, ENV['PATH']

これでシステムのPATHをそのまま使える

参考までに、scheduler.rbを載せときます。

set :output, "/home/hoge/application/log/whenever.log"
set :environment, :development

env :PATH, ENV['PATH']

every '0,15,30,45 * * * *' do
  rake 'twitter:tweet'
end

ちなみに、wheneverのインストールはここを参考

Wheneverは導入が超簡単なcrontab管理ライブラリGemです![Rails4.2 x Ruby2.3] - 酒と泪とRubyとRailsと