2016-12-12 15 views
1

私は、別のコントローラーに渡す必要のあるオブジェクトを格納するAngularファクトリーを作成しました。工場は次のようになります:角度ファクトリーでの双方向バインディング

app.factory('SearchEngineConfigs', function() { 
    var configs = { 
     isInternational: false, 
     TripType: 1, 
     journeys: [] 
    } 
    var _setInternational = function(val) { 
     configs.isInternational = val; 
    } 
    var _setTripType = function(val) { 
     configs.TripType = val; 
    } 
    var _setJourneys = function(journeys) { 
     configs.journeys = journeys; 
    } 

    var _getConfigs = function() { 
     return configs; 
    } 
    return { 
     setInternatioanl: _setInternational, 
     setTripType: _setTripType, 
     setJourneys: _setJourneys, 
     getConfigs: _getConfigs 
    } 
}); 

私はこの工場を私のコントローラに注入しました。コントローラの1つでは、configsの工場の値を次のように設定しています。

これまでのところとても良いです。ここで何が起きているのかは、私が変更するたびにファクトリメソッドSearchEngineConfigs.setInternatioanlを呼び出さずに$scope.searchEngine.isInternationalと言いましょう。この変更はまだ工場に反映されているため、最初のコントローラと同時にそのファクトリを使用している別のコントローラでこのプロパティを更新します。これを避けるにはどうすればいいですか?私は、明示的に対応するファクトリメソッドへの呼び出しを行うときに、ファクトリ内のオブジェクトの値を変更したいだけです。

答えて

1

あなたが工場外に存在するために、あなたの内部状態のオブジェクトへの参照を可能にすることを避けるためにangular.copyを使用することができます。
リークを引き起こす可能性があるため、入力と出力の両方でこれを行う必要があることに注意してください。

function decorate(func) { 
    return function() { 
     const argumentsCopy = _.map(arguments, a => angular.copy(a)); 
     const result = func.apply(factory, argumentsCopy); 
     return angular.copy(result); 
    }; 
} 

...今度は次のように使用されます:

var factory = { 
    setInternatioanl: decorate(_setInternational), 
    setTripType: decorate(_setTripType), 
    setJourneys: decorate(_setJourneys), 
    getConfigs: decorate(_getConfigs) 
} 
return factory 
+0

あなたのソリューションがうまく機能し、これを保証する
一つの方法は、一貫性がデコレータ機能を使用することですでした!なぜあなたはapply関数を使い、最初の引数であるようにファクトリを渡したのですか? –

+1

'this'キーワードが期待どおりに工場を参照し続けるようにします。また、 'argumentsCopy'配列が正しく展開されます。あなたの関数が 'this'を使用していた場合や、複数の入力引数を持っていた場合には、その差をもっと知ることができます。 –

0

newキーワードを使用すると、サービスの異なるインスタンスを持つことができます。

var searchEngineConfigs = new SearchEngineConfigs();のようなものを使用して、それを使用してファクトリメソッドを呼び出します。

または、angular.copy()を使用して、サービスの変数を設定して、サービスの更新を引き起こしている参照を削除することができます。

何かのように、

var _setInternational = function(val) { 
    configs.isInternational = angular.copy(val); 
} 
関連する問題