一尘不染

AngularJS:何时将$ scope变量传递给函数

angularjs

我正在使用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>

注意 ng-submit 指令如何在不将 newTodo 模型作为参数传递的情况下调用 addTodo() 函数。 __

不久之后,我在第19行的同一文件中遇到了以下代码:

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

您可以看到作者这次决定将 allChecked 模型传递给 markAll() 函数。如果我理解正确,他们可能在控制器内部引用了 $
scope.allChecked
而不是将其传入。

为什么要在同一文件中使用两种不同的方法?在某些情况下,一种方法更好吗?这是不一致的情况还是正在使用更深层的逻辑?


阅读 226

收藏
2020-07-04

共1个答案

一尘不染

我希望始终将参数传递给该函数:

  • 函数可以清楚知道哪些参数。
  • 因为 所有参数都已注入到函数中 ,所以单元测试更容易。(适用于单元测试)

请考虑以下情况:

$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,您会注意到类似的东西:该框架尝试将参数注入到动作函数中,而不是直接从对象RequestHttpContext对象中访问它。

万一其他人提到喜欢与 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
        }   
    }
2020-07-04