2009-03-24 8 views
4

私は、Webアプリケーション用のJavaScriptでコンテキストメニューを作成しています。メニューはさまざまなコンテキストで表示され、さまざまな選択肢があります。私は各コンテキスト/選択肢ごとに異なる機能を持つことができます。ネストされたスイッチを回避する方法は?

grid1_delete() 
grid1_duplicate() 
grid2_delete() 
grid2_add() 
grid2_duplicate() 

これらのコードはメニューがビルド中です。私が気に入っていないことは、繰り返しコードがたくさんあることでしょう。だから私はディスパッチャー関数を使用することを考えていましたが、その結果、潜在的に長いネストされたswitch文が作成されていました。より良い方法が必要です。多分、ディスパッチャーはそれが価値よりも面倒です。私はtherelatedpostsのいくつかを見てきましたが、私はこの正確な状況にそれらをどのように適用するかについてはあまり理解していません。

+0

異なるグリッドが異なる機能をサポートしているか、それらがすべて同じセットをサポートしていますか? –

+0

grid1_deleteとgrid2_deleteの違いがわかりません。彼らは別のオブジェクトで同じことをしますか?あるいは、彼らは根本的に異なることをしますか?前者の場合は、それらを1つの汎用関数に結合する必要があります。 – Miles

+0

異なるグリッドは異なる機能をサポートします。さらに悪いことに、同じグリッドの異なる行は異なる機能、および/または異なるタイプのオブジェクトに作用する同様の機能をサポートします。理論的には、いくつかのリファクタリング/パラメタライゼーションが発生する可能性がありますが、すべてのケースでそうでない場合もあります。 – sprugman

答えて

7

Javascriptでは、switch文はほとんど必要ありません。一般的には、辞書や地図などのオブジェクトを使用して直接検索することができます。foo.barfoo['bar']に相当します。 「グローバル」変数のためのまた

some_global_func()var f = 'some_global_func'; window[f]()のように書くことができwindow.some_global_func()、と同等です:あなたは今まで変数を選択するか、動的にその名前に基づいて関数を呼び出すためにevalを必要としません。ただし、一般的には、グローバルスコープではなくオブジェクト(つまりwindowオブジェクト)に関数を格納する方がよいでしょう。しかし、

var grid_actions = { 
    'grid1': { 
     'delete': function() { /* ... */ }, 
     'duplicate': function() { /* ... */ } 
    }, 
    'grid2': { 
     'delete': function() { /* ... */ }, 
     'add': function() { /* ... */ }, 
     'duplicate': function() { /* ... */ } 
    } 
} 

function contextMenuClick(context, menuItem) { 
    var action = menuItem.innerHtml; 
    if (context in grid_actions) { 
     if (action in grid_actions[context]) { 
      grid_actions[context][action](); 
     } else { 
      console.log('undefined action in contextMenuClick/' + context + ': ' + action); 
     } 
    } else { 
     console.log('undefined context in contextMenuClick: ' + context); 
    } 
} 

よりよい解決策を:

ので、grid1_deletegrid2_deleteは根本的に異なっており、一般的な機能に組み合わせることができないと仮定して、あなたは非常にあなたのコードを変更せずに、次のような何かを行うことができますこれらの機能が@le dorfierのように、各コンテキストのオブジェクトのメソッドになるようにリファクタリングすることです。

1

各スイッチにすべてのスイッチを含むすべてのスイッチを付けるのが最も簡単な方法です。

コンテキストごとにオブジェクトがある場合は、メニューを引数として受け入れる各オブジェクトに関数を追加できます。

0

eval(context + "_" + action + "();"を使用する行に沿ったものは、おそらく動作しますが、クライアントがスクリプト内のほぼ任意の関数を実行できる。 (X_Yと一致するもの)。はい。 evalはほとんど悪です。

どの程度

switch(context+"_"+action) { 
    case ("grid1_add"): grid1_add(); 
[...] 
} 
2

方法だけではなく、文字列の「文脈」のための実際のオブジェクト参照を渡すことについてはどうですか?そうすれば、スイッチのステートメントは1つだけです。

さらに、ハンドラを正しいオブジェクト/メソッドに直接バインドするだけで簡単にできます。

関連する問題