为什么这个角度js todo app只检查一次if语句?

时间:2013-07-06 10:59:16

标签: angularjs

在函数$ scope.addTodo()中,我的浏览器仅在第一次进入$ scope.todos数组时评估if语句。在我创建一个todo之后,我现在可以推送空白todos,即使这不是理想的结果。奇怪的是,如果我从

更改if语句
if ($scope.formTodoText != null)

if ($scope.formTodoText != "")

然后我可以提交一个空白的待办事项,但只能提交一次。在提交初始空白待办事项之后,评估没有问题。

<!DOCTYPE html>
<html ng-app>
<head>
<script src="http://documentcloud.github.io/underscore/underscore-min.js"></script>
<script src="http://code.jquery.com/jquery.min.js"></script>
<link href="http://twitter.github.io/bootstrap/assets/css/bootstrap.css" rel="stylesheet" type="text/css" />
<link href="http://twitter.github.io/bootstrap/assets/css/bootstrap-responsive.css" rel="stylesheet" type="text/css" />
<script src="http://twitter.github.io/bootstrap/assets/js/bootstrap.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
<style type="text/css">
  .done-true {
    text-decoration: line-through;
    color: grey;
  }
</style> 

</head>
<body>

  <div ng-controller="TodoCtrl" class="container">

    <h2>Total Todos: {{getTotalTodos()}}</h2>
    <ul class="unstyled">
      <li ng-repeat="todo in todos">
        <input type="checkbox" ng-model="todo.done"> 
        <span class="done-{{todo.done}}">{{todo.text}}</span>
      </li>
    </ul>
    <form class="form-horizontal">
      <input type="text" ng-model="formTodoText" ng-model-instant>
      <button class="btn" ng-click="addTodo()"><i class="icon-plus"></i>Add</button>
    </form>
    <button class="btn-large" ng-click="clearCompleted()"> <i class="icon-trash"></i> Clear</button>
  </div>
  <script type="text/javascript">
    function TodoCtrl($scope) {


      $scope.todos = [
        {text: 'Learn angular', done: false},
        {text: 'Build an app', done: false},
        {text: 'Design UI', done: false}
      ];

      $scope.getTotalTodos = function() {
        return $scope.totalTodos = $scope.todos.length;
      };

      $scope.clearCompleted = function () {
        $scope.todos = _.filter($scope.todos, function (todo) {
            return !todo.done;
        });
      };

      $scope.addTodo = function() {
        if ($scope.formTodoText != null) {
            $scope.todos.push({text:$scope.formTodoText, done: false});
            $scope.formTodoText = "";
        }
      };
    }

  </script>
</body>
</html>

1 个答案:

答案 0 :(得分:2)

首先,您应该使用!=====运算符(而不是!===运算符)进行JavaScript比较。

您可能还会发现console.log方便。尝试添加

    console.log($scope.formTodoText);

作为$scope.addTodo函数体的第一行,以查看它包含的内容。

对于第一种情况,您使用过:

    if ($scope.formTodoText != null) {

最初,我们无法提交空的待办事项(未对输入字段进行某种编辑),因为$scope.formTodoTextundefined。这会导致if ($scope.formTodoText != null)检查失败,因此不会添加。但是,如果您在输入字段中键入一些字符然后将其删除,您会发现仍然可以添加空待办事项,因为$scope.formTodoText将成为空字符串'' != null,因此我们输入if正文并添加空的待办事项。

现在,假设我们创建了一个非空的待办事项。这会调用$scope.addTodo函数。由于$scope.formTodoText不为null,因此将todo推送到列表中。然后,它将$scope.formTodoText重置为空字符串。这就是我们能够在不编辑输入字段内容的情况下从此处添加空待办事项的原因,因为$scope.formTodoText设置为空字符串而'' != null

如果相反,我们使用:

    if ($scope.formTodoText != '') {

然后点击添加按钮(之前没有对输入字段做任何事情),然后$scope.formTodoTextundefinedundefined != '',所以我们进入了if声明。然后将{text: undefined, done: false}推送到$scope.todos。在此之后,$scope.formTodoText被设置为空字符串,并且添加作为空字符串的待办事项从此时起失败。

为了防止空洞的待办事项,一种方法是将条件更改为:

    if ($scope.formTodoText) {

因此$scope.formTodoText会检查$scope.formTodoText是否为“真实”值,该值会自动排除“虚假”值,特别是undefined和空字符串。有关truthy和falsy值的更多信息,请参阅http://docs.nodejitsu.com/articles/javascript-conventions/what-are-truthy-and-falsy-values