3

Harmonyプロキシ(Node.js)を使用してJavaScriptで記述された動的サービスロケーターを取得しようとしています。基本的に、新しいコンテナを作成します。

 var container = new Container();

そうすれば、従来のサービスロケーターのように値を設定して取得できるようになります。

 container.set('FM', {});
 container.get('FM');
 container.get('FM', function(FM) {

 });

サブオブジェクトのように機能する名前空間を持つこともできます。

 container.set('FM.Object', {});

問題は動的エイリアスにあります。

 var App = container.alias('App');

エイリアスを作成すると、従来のオブジェクトのように操作できる新しいプロキシオブジェクトが作成されますが、これはメソッドのエイリアスget()ですset()

それ以外の:

 container.get('App.Hello'); 

エイリアスを使用すると、次を使用します。

 App.Hello

問題は深い名前空間にあります。アクセスしようとしているとしましょう。App.Hello.World.Controllerこれは、プロキシを一度に1つの名前空間を通過し、一度にすべてを通過するわけではないためです(完全な名前空間のように)。ユーザーがサービスロケーターに格納されている値を取得するために呼び出しているApp.Helloかどうか、またはユーザーがより深い名前空間にアクセスし続けたいかどうかをどのように知ることができますか?あなたはできません(私が試したことから)。

これを達成する他の方法はありますか?

App.Hello.Worldより深い名前空間にアクセスする場合はプロキシ、またはサービスロケーターに格納されている値のいずれかを返す構文を持つ。

  var App = container.alias('App');
  App.Controller.Home.Method.Index
  // It would go through:
  App -> Proxy
  App.Controller -> Proxy or Value?
  App.Controller.Home -> Proxy or Value?
  App.Controller.Home.Method -> Proxy or Value?
  App.Controller.Home.Method.Index -> Proxy or Value?

今、私は2つのオプションを扱うための規則をまとめました。値を取得するために単数形の名前を使用し、プロキシを返すために複数形を使用します。これはあまり効果的ではないため、簡単な「ハック」でした。

(説明や詳細情報が必要な場合は、私に知らせてください)

4

1 に答える 1

5

問題の概要

私があなたを正しく理解しているかどうか見てみましょう。「一緒に」アクセスされるプロパティを、の単一のキーの一部と見なしたいようですcontroller.get。次の例を見てください。

controller.set('App.Foo.Bar', { Zap: 1 });
controller.set('App.Foo.Bar.Zap', 2);

var App = controller.alias('App');

var Bar = App.Foo.Bar;
var Zap = Bar.Zap;

var Zap2 = App.Foo.Bar.Zap;

console.log(Zap, Zap2);
// should log: 1, 2

上記の動作が必要な場合は、(その構文では)不可能です。JavaScriptはとを区別しませApp.Foo.Bar.Zapvar Bar = App.Foo.Bar; Bar.Zapvar Bar = App.Foo.Bar「一緒に」アクセスされたプロパティ( )と「別々に」アクセスされたプロパティ()を区別できる言語には何もありませんBar.Zap


提案

ただし、構文を変更することで近づけることができます。私はいくつかの異なる可能性について考えました、そしてここに私が思いつくことができる最高のものがあります:

controller.set('App.Foo.Bar', { Zap: 1 });
controller.set('App.Foo.Bar.Zap', 2);

var App = controller.alias('App');

// Use parens to note that we are ending the key name
// and want it to retrieve a value.
var Bar = App.Foo.Bar();
var Zap = Bar.Zap;

var Zap2 = App.Foo.Bar.Zap();

console.log(Zap, Zap2);
// should log: 1, 2

上記のように、プロパティの取得後に括弧を追加すると、この構文をプロキシへの識別メモとして使用できます。これは、コントローラから値を取得することを意味します。


実装

これを可能にするコードは次のとおりです。

var Container = (function() {

    return function Container() {

        var map = { };

        this.get = function get(key) {
            return map[key];
        };

        this.set = function set(key, value) {
            map[key] = value;
        };

        this.alias = function alias(name) {
            return createAlias(this, name);
        };

    };

    function createAlias(container, aliasName) {
        return new Proxy(
            function() {
                return container.get(aliasName);
            },
            {
                get: function(target, name) {
                    return createAlias(container, aliasName + '.' + name);
                },
                set: function(target, name, value) {
                    container.set(aliasName + '.' + name, value);
                }
            }
        );
    }

})();

で設定=および取得できます()

var container = new Container();
container.set('App.Controller.Home.Method.Index', 5);

var App = container.alias('App');

App.Controller.Home.Method = 7;

console.log(
    App.Controller.Home.Method(),      // => 7
    App.Controller.Home.Method.Index() // => 5
);

ファイナルノート

プロキシは実験的なものであることをご存知だと思いますが、ES6のこの特定の機能はまだかなり流動的であることを強調したいと思います。現在の直接プロキシの提案が最終的に言語に含まれる可能性がありますが、ESのプロキシが来年に大幅に変更される可能性もあります。(この1か月間、プロキシの提案に関してECMAScriptメーリングリストで活発な議論がありました。)少なくともNodeでは、プロキシが大幅に変更された場合(古い実装の更新に取り組んでいる間)、古いバージョンのNodeを使い続けることができます。

お役に立てれば!

于 2013-01-23T15:15:00.327 に答える