2016-10-13 10 views
1

ボイラープレートのコードを減らそうとすると、一般的なフォームフィールドのハンドラを悪いフィールドを強調表示するハンドラオブジェクトに追加しようとしています。この:プログラマチックにフォームハンドラに反応するハンドラを追加する

//FieldHelper.js 
exports.withStandardStoreHandlers = function (storeObj, fields) 
{ 

    for(var i = 0; i < fields.length; i++) 
    { 
     var f = fields[i]; 
     var midName = f.charAt(0).toUpperCase() + f.slice(1); 

     storeObj.prototype["onUpdate" + midName] = function(event) { 

      this[""+f] = event.target.value; 
      this[f+"ValidationState"] = ''; 
      this[f+"HelpBlock"] = '';  
     }; 
    } 
    return storeObj; 
} 

と、最終的に私はAltキーストアを作成し、それはthuslyエクスポートされます。

export default alt.createStore(FieldHelper.withStandardStoreHandlers(AddressStore, "firstName", "lastName", "street")); 

そして、それは実際には、 "onUpdateFirstName"、 "onUpdateLastName" を追加などの方法が、残念ながらありません彼らはすべて最後に渡されたフィールドを使います。したがってこの例では、名前にいくつかのものを入力しますが、onUpdateFirstNameはストリートテキストフィールドとその検証ステート/ヘルプブロックを変更します。

明らかに、ソリューションは何らかの形で "f"と "midName"変数のコピーを作成して、動的に作成されたonUpdateXメソッドのそれぞれが最後に使用可能なものを使用するのではなく、 JavaScriptでこれを行う方法を理解できません。可能な限り下位互換性のある方法で、これがフロントエンド上にあることが望ましい。

答えて

1

JavaScriptのvarは、コードが期待しているようにスコープをブロックするのではなく、機能スコープであるためです。より良い説明はここで見つけることができます:https://stackoverflow.com/a/750506/368697

一つの解決策は必ずあなたのfforEachを使用することにより、各反復での関数のスコープ内で宣言されていることを確認することです:

//FieldHelper.js 
exports.withStandardStoreHandlers = function (storeObj, fields) 
{ 
    fields.forEach(function (f) { 
     var midName = f.charAt(0).toUpperCase() + f.slice(1); 

     storeObj.prototype["onUpdate" + midName] = function(event) { 

      this[""+f] = event.target.value; 
      this[f+"ValidationState"] = ''; 
      this[f+"HelpBlock"] = '';  
     }; 
    }); 
    return storeObj; 
}