Trouble with basic todo app angular js

2019-09-03 15:25发布

I am a newbie to this framework struggling to understand scope .

I followed the basic steps for creating a todo app given in the yeoman website.

Here is my code :

Index.Html

<!doctype html>
<html class="no-js">
<head>
    <meta charset="utf-8">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width">
    <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="styles/main.css">
</head>
<body ng-app="mytodoApp">
    <div class="container" ng-include="'views/main.html'" ng-controller="MainCtrl"></div>
    <script>
        (function (i, s, o, g, r, a, m) {
            i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
                (i[r].q = i[r].q || []).push(arguments)
            }, i[r].l = 1 * new Date(); a = s.createElement(o),
            m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
        })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
        ga('create', 'UA-XXXXX-X');
        ga('send', 'pageview');
    </script>
    <script src="bower_components/jquery/dist/jquery.js"></script>
    <script src="bower_components/angular/angular.js"></script>
    <script src="bower_components/json3/lib/json3.js"></script>
    <script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
    <script src="scripts/app.js"></script>
    <script src="scripts/controllers/main.js"></script>
</body>
</html>

Main.Html

<div class="container">
    <h2>My todos</h2>

    <!-- Todos input -->
    <form role="form" ng-submit="addTodo()">
        <div class="row">
            <div class="input-group">
                <input type="text" ng-model="todo" placeholder="What needs to be done?" class="form-control">
                <span class="input-group-btn">
                    <input type="submit" class="btn btn-primary" value="Add">
                </span>
            </div>
        </div>
    </form>
    <p></p>

    <!-- Todos list -->
    <div ui-sortable ng-model="todos">
        <p class="input-group" ng-repeat="todo in todos" style="padding: 5px 10px; cursor: move;">
            <input type="text" ng-model="todo" class="form-control">
            <span class="input-group-btn">
                <button class="btn btn-danger" ng-click="removeTodo($index)" aria-label="Remove">X</button>
            </span>
        </p>
    </div>
</div>

Main.js

'use strict';
angular.module('mytodoApp')
  .controller('MainCtrl', function ($scope) {
      $scope.todos = ['Item 1', 'Item 2', 'Item 3'];
      $scope.addTodo = function () {
          $scope.todos.push($scope.todo);
          $scope.todo = '';
      };
      $scope.removeTodo = function (index) {
          $scope.todos.splice(index, 1);
      };
  });

App.JS

'use strict';
angular
  .module('mytodoApp', []);

When i click on add button, the $scope.todo is undefined and its adding an item showing empty text box.

The delete functionality is working absolutely fine.

I guess the problem is with the scoping . Can any one care to guide me with regards to this ?

Updated :

Please find below screen

enter image description here I am not getting any error rather the output is wrong.

This is what heppening when trying to add a new item.

2条回答
我命由我不由天
2楼-- · 2019-09-03 15:34

ngController executes at priority level 500, while ngInclude executes at priority level 400.

So first, ngController will create a scope, then ngInclude. That is to say, in your included HTML file, every time you want to access a variable scoped in your controller, you'll need to prefix with $parent, e.g. ng-submit="$parent.addTodo()".

The other solution (better IMHO) is to remove the ngController attribute from the div which has the ngInclude, and to put it in on the surrounding div within your HTML file:

Index.html:

<div class="container" ng-include="'views/main.html'"></div>

Main.html:

<div class="container" ng-controller="MainCtrl">
    ...
</div>
查看更多
等我变得足够好
3楼-- · 2019-09-03 15:39

hey you are mixing scopes here first you have a todo for a new item and another "the same" todo for each element in the ng-repeat and also you don't need to re-define ng-model inside of the repeater just use the curly brackets notation for referencing to the scope.

change the name ng-repeat like:

<div>
        <p class="input-group" ng-repeat="element in todos" style="padding: 5px 10px; cursor: move;">
            <span>{{element}}</span>
            <span class="input-group-btn">
                <button class="btn btn-danger" ng-click="removeTodo($index)" aria-label="Remove">X</button>
            </span>
        </p>
    </div>

EDIT:

this is a working version of what you got

http://plnkr.co/edit/CrNrryNTiFFqzhWxaM7P

plnker code:

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.2.25/angular.js" data-semver="1.2.25"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
     <h2>My todos</h2>

    <!-- Todos input -->
    <form role="form" ng-submit="addTodo()">
        <div class="row">
            <div class="input-group">
                <input type="text" ng-model="todo" placeholder="What needs to be done?" class="form-control">
                <span class="input-group-btn">
                    <input type="submit" class="btn btn-primary" value="Add">
                </span>
            </div>
        </div>
    </form>
    <p></p>

    <!-- Todos list -->
    <div ui-sortable ng-model="todos">
        <p class="input-group" ng-repeat="element in todos" style="padding: 5px 10px; cursor: move;">
            {{element}}
            <span class="input-group-btn">
                <button class="btn btn-danger" ng-click="removeTodo($index)" aria-label="Remove">X</button>
            </span>
        </p>
    </div>
  </body>

</html>

controller:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.todos = ['Item 1', 'Item 2', 'Item 3'];
      $scope.addTodo = function () {
          $scope.todos.push($scope.todo);
          $scope.todo = '';
      };
      $scope.removeTodo = function (index) {
          $scope.todos.splice(index, 1);
      };
});
查看更多
登录 后发表回答