優れた責任と優れた力-AngularJS Safety

画像



間違いなく、角度はあなたに強さを与えます。 しかし、彼女は賢く使われる必要があります。 私はこれに違反して何度も苦しんだ3つの簡単なルールを策定しようとしました。



1.不要な変更が発生する可能性がある場合は、オブジェクトのコピーを作成します。



Angularでは、デフォルトのデータは同じであり、意図的、偶然、またはエラーの結果としてそれを変更すると、その使用のすべての場所が危険にさらされます。 たとえば、フォームに入力するために使用される空のエンティティのファクトリがあります。

module.factory("emptyEntity", function() { var emptyObject = { name:"", surname:"", address:{ city:"" street:"", } }; return { createEmptyEntity: function(){ return emptyObject; } }; });
      
      





さらに、フォームコントローラーで、この空のオブジェクトを$スコープで作成し、フォームモデルとして使用します。

  $scope.model = mapper.createEmptyPetition();
      
      





フォームに入るときにこのモデルが変更され、別のフォームに対してmapper.createEmptyPetition()を再度呼び出すとどうなりますか? emptyObjectの同じインスタンスがどこでも使用されるため、変更がそれに反映され、次回mapper.createEmptyPetition()を呼び出すときに、ダーティで使用済みのオブジェクトが取得されます。 開発中にこのような瞬間が多数発生する可能性があるため、オブジェクトへの参照を左右に配布する場合は注意が必要です。 この場合、次のようにする必要があります。変更が元のオブジェクトに影響を与えないように、オブジェクトのコピーを返します。

  createEmptyEntity: function(){ return angular.copy(emptyObject); }
      
      





2.データの同期を失いたくない場合は、オブジェクト/配列への参照を失ってはいけません



簡単な例。

$スコープ内に配列を持つコントローラーがあり、配列をクリアする関数があります。

 module.controller("NewPetitionController", ["$scope", function($scope) { $scope.myArray = [1,2,3,4]; $scope.cleanArray = function(){ $scope.myArray = []; } } ]);
      
      





そして、ビューのどこかで、たとえば配列を描画するディレクティブに配列を渡します。

 <div my-array-viewer array="myArray"></div>
      
      





cleanArray関数を呼び出すとどうなりますか? ディレクティブは、まだ古いリンクへのリンクがあるため、古き良きフルアレイを静かに表示し続けます。 また、コード "$ scope.myArray = []"を使用して、新しい配列を作成し、myArrayプロパティにその配列へのリンクを記述しました。これには、my-array-viewerディレクティブが完全に並行しています。 参照を失うことなく配列をnullにするには、$ scope.myArray.length = 0;を呼び出すだけです。

オブジェクトについても同じことが言えます。 新しいオブジェクトを取得して変数に割り当てることはできません。古いオブジェクトを変更して、このオブジェクトへのリンクを持っているアプリケーションの残りが失われないようにする必要があります。

 module.controller("NewPetitionController", ["$scope", function($scope) { $scope.myObj = {foo: "bar"}; $scope.setObj = function(newObj){ //$scope.myObj = newObj; //  ,      angular.extend($scope.myObj, newObj); //  ,     } } ]);
      
      





3. $スコープの子には注意してください



ng-if、ng-includeなどの多くのディレクティブは、$スコープの子を作成します。 これはどういう意味ですか? これらのディレクティブは$ scopeの新しいインスタンスを作成し、そのプロトタイププロパティには親スコープがあります-標準javascript継承。 継承中に単純なプロパティがコピーされるため、子スコープの単純なプロパティ(文字列、数値、ブール値など)を変更しても、親スコープには影響しません。 それらとは対照的に、プロトタイプ継承のオブジェクトはリンクによって渡されるため、オブジェクトのプロパティの変更は親スコープに表示されます。

したがって、これは実行しないでください。これは機能しません。

 <div ng-if="true"> <a ng-click="showSecondBlock = true">  </a> </div> <div ng-if="showSecondBlock">   ! </div>
      
      





代わりに、そのようなことのために$スコープに特別なオブジェクトが必要です。それをviewModelと呼びましょう

 app.controller("MainCtrl", function($scope) { $scope.viewModel = {}; });
      
      





 <div ng-if="true"> <a ng-click="viewModel.showSecondBlock = true">  </a> </div> <div ng-if="viewModel.showSecondBlock">   ! </div>
      
      







あなたがたまたま円錐を埋めた角道のその他の特徴についてのコメントを書いてください。



All Articles