TypeScript:OnExit装饰器

时间:2017-03-26 17:41:40

标签: typescript

说明:

我有以下结构: Item对象包含Group(s)数组,每个组包含User(s)数组。 Item具有以下API: addUserremoveUseraddGroupremoveGroupaddUnitremoveUnit。 每个操作都会触发每个用户rank属性的新计算(针对特定组)。

我正在寻找一种方法,在每个API的操作结束时,方法calcRank将被触发,而不会显式调用它(类似于OnExit装饰器)。

1 个答案:

答案 0 :(得分:1)

The Advice Pattern在一种像JavaScript一样动态的语言中非常简单:

function before(behavior) {
  return method => function beforeHandler(...args) {
    behavior.apply(this, args);
    return method.apply(this, args);
  };
}

function after(behavior) {
  return method => function afterHandler(...args) {
    const result = method.apply(this, args);
    behavior.apply(this, [args, result]);
    return result;
  };
}

const id = _ => _;

function withAdvice({before: beforeBehavior = id, after: afterBehavior = id, skip: [] }) {
  return Class => Object.keys(Class.prototype).forEach(methodName => {
    if (!skip.contains(methodName)) {
      const method = Class.prototype[methodName];
      const afterDecorator = after(afterBehavior);
      const beforeDecorator = before(beforeBehavior);
      Class.prototype[methodName] = afterDecorator(beforeDecorator(method));
    }
  });
}


@withAdvice({
  after() {
    this.calcRank();
  },
  skip: ['calcRank']
})
class Item {
  addUser() {}
  removeUser() {}
  addGroup() {}
  removeGroup() {}
  addUnit() {}
  removeUnit() {}
  calcRank() {}
}