2016-10-20 7 views
0

角度範囲外の関数(「insertTstData」という名前)を宣言しました。(コントローラ内などでもありません) ( "remark"という名前の)コントローラ内でローカル変数( "save")を呼び出すと、ローカル変数を変更し、その変更はスコープ内の変数と同じ内容の他のすべての変数に反映されますいずれにせよ!)。スコープ外の関数は、アクセスできないはずのAngularJS変数を変更します。

私はあなたに全体の流れを伝えることなくそれを説明する方法を知りません。

まず、$ httpサービスを使用してJSON構成ファイルを取得し、それを格納するスコープ変数を作成します(ここでは、「remark」の親である「メイン」コントローラにいます) 、)バグが発生している:

$http.get(path + 'remarkConfig.json') 
     .then(function (response) { 
      //change fields 
      $scope.remark = response.data; //this variable will get used later on 
      $scope.dummy = response.data; //this variable will be changed even if not used anymore 
}); 

これらの変数は、オブジェクトの配列ですが、シンプルさのは、彼らは二つのプロパティを持つオブジェクトです言わせてのために:

{"p1":"PROP ONE", "p2": "PROP TWO"} 

、私は内部のボタンを持っています関数を呼び出して$ scope.remarkをそれに渡す "remark"コントローラ:

<md-button class="amaButton md-raised" ng-click="save(data, remark)" aria-label="save">{{translate.save}}</md-button> 

ここ(「メイン」スコープを注入されている)「発言」コントローラの範囲内の保存機能です:今

$scope.save = function (data, remarks) { 
    console.log($scope.dummy); 
    console.log($scope.remark); 
    console.log(remarks); 
    //all these variables still contain the original values 
    var originalRemarks = {}; //another dummy variable, just to be sure 
    originalRemarks.codes = remarks; 
    //insert TSTs into data, formatting <>-like remarks 
    var response = insertTstData(data, $scope.tst, remarks); //this is the function which wreaks havoc, I pass to it the variable remarks by value (or at least I thought so) 
    console.log($scope.dummy); 
    console.log($scope.remark); 
    console.log(remarks); 
    console.log(originalRemarks.codes); 
    //they ALL changed! 
} 

は、のは、バグが(覚え原因となる機能を見てみましょう、任意のコントローラ/スコープの外にあります)。 のすべての機能は、他の2つの引数に応じて、ローカル変数(発言へのセットを=)を変更し、応答を返しているん:

function insertTstData(data, tst, remarks) { 
    var rem = remarks; 
    rem.p1=""; 
    var response={"data": data, "remarks": rem}; 
    return response; 
} 
//after these function returns, every variable's p1 is set to an empty string! 

私は、これはそれが起こるれている点と、これらの変数である完全に確信していますコード内では何も変更されません(昨日何時間もデバッグして無駄になりました)。

私は間違っていますか?彼らは私が気づいていないいくつかの奇妙な整備士のために、同じ価値観へのすべてのポインタですか?

+0

あなたはisuueの簡単なデモを作成できますか?把握するのは簡単でしょう。 – Manish

答えて

0

変数rem(var rem = remark)を作成すると、javaScriptは元のオブジェクトの複製を作成するのではなく、元のオブジェクトへの参照を作成します。したがって、remを変更しても、親オブジェクトに変更が加えられます。

複製オブジェクトを作成するには、clone()メソッドを使用することをお勧めします。

このlinkフォロースルーのjs

+0

実際にはオブジェクトの配列ですが、これは実際には機能しました! 私はそれほど奇妙なことをやろうとしたので、決して考えなかった – Kitra

+0

実際にはオブジェクトの配列ですが、これは実際には機能しました! 私は奇妙なことをしようとして以来、私は決して考えなかった var rem = []; for(var i = 0; i Kitra

0

にオブジェクトのクローンを作成するためのあなたはまた、いずれかのオブジェクトまたは配列にすることができ、オブジェクトのディープコピーを作成するためにangular.copy(remarks)を使用することができます。

1

これは、変数のシャローコピーとディープコピーの違いです。 オブジェクト(ないプリミティブ型)の簡単な割り当てが常に、例えば

var remarks = {"p1":"PROP ONE", "p2": "PROP TWO"} 
var rem = remarks; //the assignment 

REMオブジェクト備考を参照すると、すべての変更を保持することを意味し、参照(浅いコピー)することによって行われるJavaScriptで 発言のフィールドには、remとviceversaの変更が反映されます。 あなたは2つのdistintオブジェクト(深いコピー)を作成したい場合は、このようにangular.copy

var rem = angular.copy(remarks) 

を使うべき二つの変数は、このように2つの異なるオブジェクト、メモリ内の2つの差分領域に二つの異なる参照を保持します。

enter image description here

関連する問題