読者です 読者をやめる 読者になる 読者になる

ヘルパーが再描画されるタイミング

Ember.js

ユーザの名前を表示するヘルパーを作るとします。こんな感じになるでしょうか。

// app/helpers/user-name.js

import { helper } from 'ember-helper';

export default helper(([user]) => {
  return `${user.get('firstName')} ${user.get('lastName')}`;
});
{{user-name user}}

一見よさそうですが落とし穴があります。ヘルパーは引数の値自体が変化したときは再描画されますが、その先のプロパティは見てくれません。この例だと user.firstNameuser.lastName が変化しても表示内容はそのままになってしまいます。

一番簡単な対処方法は、ヘルパーの引数には常に単純な値を渡すようにすることです。

// app/helpers/user-name.js

import { helper } from 'ember-helper';

export default helper(([firstName, lastName]) => {
  return `${firstName} ${lastName}`;
});
{{user-name user.firstName user.lastName}}

それでは引数が多くなりすぎて困るようなら、クラスベースのヘルパーにするという手があります。

// app/helpers/user-name.js

import Helper from 'ember-helper';
import observer from 'ember-metal/observer';

export default Helper.extend({
  compute([user]) {
    this.set('user', user);

    return `${user.get('firstName')} ${user.get('lastName')}`;  
  },

  userDidChange: observer('user.{firstName,lastName}', function() {
    this.recompute();
  })
});
{{user-name user}}

表示を更新したいタイミングで this.recompute() を呼び出してやればよいわけです。

クラスベースのヘルパーはサービスを inject するような使い方もできます。詳しくは公式ガイドの Class-based Helpers を参照してください。