24

私はTodoMVCアプリを使用して、AngularJS フレームワークを改善しています。14 ~ 16 行目のindex.htmlには、次のように表示されます。

<form id="todo-form" ng-submit="addTodo()">
    <input id="new-todo" placeholder="What needs to be done?" ng-model="newTodo" autofocus>
</form>

newTodoモデルを引数として渡さずにng-submitディレクティブがaddTodo()関数を呼び出す方法に注意してください。

しばらくして、同じファイルの 19 行目に次のコードを見つけました。

<input id="toggle-all" type="checkbox" ng-model="allChecked" ng-click="markAll(allChecked)">

今回、作成者がallCheckedモデルをmarkAll()関数に渡すことにしたことがわかります。私の理解が正しければ、コントローラーを渡すのではなく、コントローラー内で$scope.allCheckedを参照していた可能性があります。

同じファイルで 2 つの異なるアプローチを使用するのはなぜですか? 状況によっては、1 つのアプローチの方が優れていますか? これは矛盾のケースですか、それともより深いロジックが使用されていますか?

4

6 に答える 6

32

関数に常に引数を渡すことをお勧めします。

  • 関数が期待するパラメーターがより明確になります。
  • すべてのパラメーターが関数に注入されるため、単体テストが容易になります (単体テストに適しています)。

次の状況を考慮してください。

$scope.addToDo = function(){
   //This declaration is not clear what parameters the function expects.
   if ($scope.parameter1){
      //do something with parameter2
   }    
}

さらに悪いことに:

$scope.addToDo = function(){
    //This declaration is not clear what parameters the function expects.
    if ($scope.someobject.parameter1){ //worse

    }    
}

スコープの継承parameter2は親スコープから来る可能性があるため、関数内にアクセスすると密結合parameter2が作成され、その関数の単体テストを試みるときにも問題が発生します。

次のように関数を定義すると:

//It's clearer that the function expects parameter1, parameter2
$scope.addToDo = function(parameter1, parameter2){
   if (parameter1){
      //do something with parameter2
   }    
}

親スコープから継承された場合parameter2でも、ビューから渡すことができます。単体テストを行う場合、すべてのパラメーターを渡すのは簡単です。

ASP.NET MVC を使用したことがある場合は、同様のことに気付くでしょう。フレームワークは、RequestまたはHttpContextオブジェクトから直接アクセスするのではなく、アクション関数にパラメーターを挿入しようとします。

他の人が一緒に働くように言及した場合にも適していますng-repeat

私の意見では、角度のコントローラーとモデルは明確に分離されていません。$scope オブジェクトは、プロパティとメソッドを持つモデルのように見えます (モデルにはロジックも含まれています)。OOP のバックグラウンドを持つ人々は、次のように考えるでしょう: オブジェクトに属さないパラメーターのみを渡します。クラス Person が既に を持っているように、すべてのオブジェクト メソッドhandsを渡す必要はありません。hands次のようなコード例:

//assume that parameter1 belongs to $scope, parameter2 is inherited from parent scope.
    $scope.addToDo = function(parameter2){ 
        if ($scope.parameter1){ //parameter1 could be accessed directly as it belongs to object, parameter2 should be passed in as parameter.
            //do something with parameter2
        }   
    }
于 2013-10-05T08:50:06.260 に答える
9

Zen of Angularは次のように提案しています。

テンプレートでスコープを読み取り専用として扱う
コントローラーでスコープを書き込み専用として扱う

この原則に従って、常にテンプレートのパラメーターを使用して関数を明示的に呼び出す必要があります。

prioritiesただし、どのスタイルに従うにしても、ディレクティブの実行順序に注意する必要があります。あなたの例では、とを使用するng-modelng-click、2 つのディレクティブの実行順序があいまいになります。ソリューションは、実行順序が明確な を使用しています。値が変更された後ng-changeにのみ実行されます。

于 2013-12-14T10:34:42.343 に答える
1

おそらく、あなたができることを説明するために?2 つが同じコントローラーであると仮定すると、2 つの間に機能上の違いはありません。子スコープが生成される状況があることに注意してください。その場合、コントローラーと同じスコープがなくなります。

于 2013-09-23T19:28:02.187 に答える