0

関数 $scope.addTodo() では、ブラウザは $scope.todos 配列への最初のエントリで if ステートメントのみを評価しています。単一の Todo を作成した後、空の Todo をプッシュできるようになりましたが、それは望ましい結果ではありません。奇妙なのは、if ステートメントを

if ($scope.formTodoText != null)

if ($scope.formTodoText != "")

その後、空白の todo を送信できますが、1 回だけです。最初の空白の todo が送信された後は、評価に問題はありません。

<!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>
4

1 に答える 1

2

まず、JavaScript での比較には ( and 演算子の代わりに) and演算子!==を使用する必要があります。===!===

console.logこれにも便利かもしれません。追加してみる

    console.log($scope.formTodoText);

関数本体の最初の行として、その$scope.addTodo内容を確認します。

使用した最初のケ​​ースの場合:

    if ($scope.formTodoText != null) {

最初は、空の todo を送信することはできません (入力フィールドでなんらかの編集を行うことなく$scope.formTodoText) undefined。これによりif ($scope.formTodoText != null)チェックが失敗するため、追加されません。ただし、入力フィールドにいくつかの文字を入力してからそれらを消去する$scope.formTodoTextと、空の文字列とになるため、空の todo を追加できることがわかります。そのため、本文'' != nullを入力して空の todo を追加します。if

ここで、空ではない単一の Todo を作成するとします。これにより、関数が呼び出され$scope.addTodoます。は null ではないため$scope.formTodoText、これにより todo がリストにプッシュされます。$scope.formTodoTextその後、空の文字列にリセットされます。これが、ここから入力フィールドの内容を編集せずに空の todo を追加できる理由です$scope.formTodoText'' != null

代わりに、次を使用します。

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

次に、追加ボタンをクリックします (その前に入力フィールドには何もしません)。その後、 、およびに$scope.formTodoTextなるので、ステートメントの本文に入ります。これに続いて、 が にプッシュされます。その後、は空文字列に設定され、空文字列である todo の追加はこの時点から失敗します。undefinedundefined != ''if{text: undefined, done: false}$scope.todos$scope.formTodoText

空の Todo を防ぐには、条件を次のように変更する方法があります。

    if ($scope.formTodoText) {

したがって、それが「真実の」値である$scope.formTodoTextかどうかをチェックし$scope.formTodoText、「偽の」値、特にundefined空の文字列を自動的に除外します。真偽値の詳細については、http: //docs.nodejitsu.com/articles/javascript-conventions/what-are-truthy-and-falsy-values を参照してください。

于 2013-07-06T12:41:12.483 に答える