表示順の入れ替え(3)

2015/10/25

前回作ったサーバー側 API を利用してタスクの表示順を入れ替える機能を完成させましょう。


現時点における TodoList#renderButtons メソッドのコードは次の通りです(app/assets/javascripts/todo_list.es6)。

  renderButtons(m, task, index) {
    m.onclick(e => this.editTask(task));
    m.span('Edit', { class: 'button' });
    m.onclick(e => {
      if (confirm('Are you sure you want to delete this task?'))
        this.agent.destroyTask(task);
    });
    m.span('Delete', { class: 'button' });
    if (index === 0) m.class('disabled');
    m.span({ class: 'button' }, m => m.fa('arrow-circle-up'));
    if (index === this.agent.objects.length - 1) m.class('disabled');
    m.span({ class: 'button' }, m => m.fa('arrow-circle-down'));
  }

タスクを上下に移動するための API は次のようなものです。

PATCH /api/tasks/:id/move_higher
PATCH /api/tasks/:id/move_lower

とすれば、TodoList#renderButtons メソッドをこう書き換えることになります。

  renderButtons(m, task, index) {
    m.onclick(e => this.editTask(task));
    m.span('Edit', { class: 'button' });
    m.onclick(e => {
      if (confirm('Are you sure you want to delete this task?'))
        this.agent.destroyTask(task);
    });
    m.span('Delete', { class: 'button' });
    if (index === 0) m.class('disabled');
    else m.onclick(e => this.agent.patch('move_higher', task.id));
    m.span({ class: 'button' }, m => m.fa('arrow-circle-up'));
    if (index === this.agent.objects.length - 1) m.class('disabled');
    else m.onclick(e => this.agent.patch('move_lower', task.id));
    m.span({ class: 'button' }, m => m.fa('arrow-circle-down'));
  }

追加したのは2行です。メソッド後半の else で始まる行です。

    else m.onclick(e => this.agent.patch('move_higher', task.id));

    else m.onclick(e => this.agent.patch('move_lower', task.id));

いま task.id の値が 7 だとすれば、上向きの矢印アイコンがクリックされたとき

PATCH /api/tasks/7/move_higher

という Ajax リクエストが実行されます。

上記のメソッドで使われている this.agentTaskCollectionAgent のインスタンスです。これが Ajax リクエストを実行します。

コレクションエージェント(1)TaskCollectionAgent を次のように定義しました。

class TaskCollectionAgent extends Cape.CollectionAgent {
  constructor(client, options) {
    super(client, options);
    this.basePath = '/api/';
    this.resourceName = 'tasks';
  }
}

basePath プロパティと resourceName プロパティが Ajax リクエストの URL を決定します。this.agent.patch('move_higher', task.id) というメソッド呼び出しがあれば、

  this.basePath + this.resourceName + '/' + 'move_higher' + '/' + task.id

という式により Ajax リクエストの URL が作られます。

コレクションエージェントは Ajax リクエストを行った後、サーバーからの応答を受けて、その顧客(client)である CapeJS コンポーネントを再描画(refresh)します。以上のような仕組みにより、タスクの上下移動機能が実現されています。

では、ブラウザで動作確認しましょう。

画面キャプチャ

この状態で「粗大ゴミを捨てる。」の右にある上向きの矢印アイコンをクリックすると、次のような画面に変化します。

画面キャプチャ

続いて同じタスクの下向きの矢印アイコンをクリックすると、元に戻ります。


以上でタスクの順序を入れ替える機能は完成です。また、5ヶ月間続けてきた連載 Cape.JS 入門もこれで終了とさせていただきます。

この連載では Cape.JS のルーティング機能についてまったく触れることができませんでした。このテーマについては、次の連載「続 Cape.JS 入門」で扱う予定です。お楽しみに。