2

私は、Angular 1.x を使用して Web アプリ アーキテクチャに取り組んでいます。新しいコンポーネントを定義するのはかなり簡単です:

class CustomComponent {
  constructor(dep1, dep2, dep3) {
    this.deps = { dep1, dep2, dep3 };
    /* app code */
  }

  /* link, compile, instance methods, template generators... */

  @readonly static $inject = ['dep1', 'dep2', 'dep3'];
}

私がやりたいのは、インジェクションの問題を除外することです。つまり、毎回記述this.depsしてコーディングするのではなく、ES7 のデコレータのようなものを使用して自動生成したいと考えています。static $injectコードは次のようになります。

@injectionFromCtorComponents
class MyClass {
  constructor (dep1, dep2, dep3) {
    /* app logic */
  }
}

これで、醜いですが、静的部分は実行可能です。

const angularInjectAnnotationFromCtor = (target) => {
    let regexStr = `^function ${target.name}\\\((.*)\\\)[.\\s\\S]*}$`;
    let regex = new RegExp(regexStr, 'gm');
    let ctorArgsStr = target.prototype.constructor.toString().replace(regex, '\$1');
    let ctorArgs = ctorArgsStr.replace(/ /g, '').split(',');

    target.$inject = ctorArgs;
};

ただし、コンストラクターの依存関係をインスタンスに保存することは、はるかにトリッキーです。せいぜい薄っぺらですが、私は次のことを思いつきました:

const readonly = (target, key, descriptor) => Object.assign(descriptor, { writable: false });

class AngularComponent {
  constructor () {
    let ctorArgs = [...arguments];
    let argNames = ctorArgs.pop();

    // let's leave comprehensions out of this :)
    this.deps = 
      argNames.reduce((result, arg, idx) => Object.assign(result, ({ [arg]: ctorArgs[idx] })), {});
  }
}

@angularInjectAnnotationFromCtor
class MyClass extends AngularComponent {
    constructor (one, two, three) {
      super(one, two, three, MyClass.$inject);
    }
}

ええ、これは私たちが始めた場所よりも悪いです...

それでは、質問は、これに対するより合理的な解決策を提案できる人はいますか?.. それとも、単に座って、今後数年以内にいつでも Chrome のプロキシを期待する必要がありますか?

4

1 に答える 1

2

あなたのアイデアの静的な部分は、基本的にはまったくないようなもの$injectです。無意味です。

アイデアを忘れるか、デコレータに引数を渡すことをお勧めします:

@inject('dep1', 'dep2', 'dep3')
class MyClass {
  constructor (dep1, dep2, dep3) {
    /* app logic */
  }
}

コンストラクタ部分は、古典的なデコレータ パターンを使用して行うことができます。

function inject() {
  var dependencies = [...arguments];

  return function decorator(target) {
    target.$inject = dependencies;  

    return function() {
      this.deps = {};
      dependencies.forEach((dep, index) => {
        this.deps[dep] = arguments[index];
      });

      target.constructor.apply(arguments, this);
      return this;
    }
  }
}
于 2015-07-12T12:41:15.200 に答える