2

I'm teaching myself AngularJS by trying to make a simple app. I'm having some trouble with data binding when using a controller.

todo-item.js

'use strict';

angular.module('todoItem', ['ngRoute'])

.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/todoItem', {
    templateUrl: 'todo-item/todo-item.template.html',
    controller: 'TodoItemCtrl'
  });
}])

.controller('TodoItemCtrl', [function() {
  this.test = [1, 2, 3, 4];
}]);

todo-item.template.html

<p>This is the partial for todo item.</p>
<p>
  this is just a test
</p>

<p>{{$ctrl.test}}</p>
<ul>
  <li ng-repeat="i in $ctrl.test">{{i}}</li>
</ul>

What I am seeing is the web-page display:

This is the partial for todo item.

this is just a test

So this indicates the template is rendering, however without the data binding dependent part...

If I put a console.log(this.test) in the controller code just after the line this.test = [1, 2, 3, 4], it does print the array object to the console Array(4) [ 1, 2, 3, 4 ]. So I know the controller code must be running...

What am I missing?

Also being new to AngularJS, I'm not familiar with debugging in this framework yet. How would you normally debug something like this? Can I goto the console and do something like >>$ctrl?


In case it helps here is app.js

'use strict';

// Declare app level module which depends on views, and core components
angular.module('todoApp', [
  'ngRoute',
  'todoList',
  'todoItem'
]).
config(['$locationProvider', '$routeProvider', function($locationProvider, $routeProvider) {
  $locationProvider.hashPrefix('!');

  $routeProvider.otherwise({redirectTo: '/todoList'});
}]);

and index.html:

<!DOCTYPE html>

<html lang="en" ng-app="todoApp">
<head>
  <meta charset="utf-8">
  <title>ToDo AngularJS App</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="app.css">
</head>
<body>

  <div ng-view></div>

  <script src="lib/angular/angular.js"></script>
  <script src="lib/angular-route/angular-route.js"></script>
  <script src="app.js"></script>
  <script src="todo-list/todo-list.js"></script>
  <script src="todo-item/todo-item.js"></script>
</body>
</html>
marno11
  • 561
  • 1
  • 5
  • 13

2 Answers2

0

I think you might need to provide controllerAs: '$ctrl' in your route provider, so

$routeProvider.when('/todoItem', {
  templateUrl: 'todo-item/todo-item.template.html',
  controller: 'TodoItemCtrl',
  controllerAs: '$ctrl'
});
xenocratus
  • 116
  • 4
0

To answer the question while avoiding $scope and instead using something more isolated as the AngularJS docs suggest, components is the way to go.

To achieve this I changed app.js to handle the routes and crucially use components:

'use strict';

// Declare app level module which depends on views, and core components
angular.module('todoApp', [
  'ngRoute',
  'todoList',
  'todoItem'
])
.config(['$locationProvider', '$routeProvider', function($locationProvider, $routeProvider) {
  $locationProvider.hashPrefix('!');

  $routeProvider.
  when('/todoList', {
    template: '<todo-list></todo-list>'
  })
  .when('/todoItem', {
    template: '<todo-item></todo-item>'
  })
  .otherwise({redirectTo: '/todoList'});
}]);

Then I implemented the component in todo-item.js:

'use strict';

angular.module('todoItem', ['ngRoute'])

.component('todoItem', {
    templateUrl: 'todo-item/todo-item.template.html',
    controller: 'TodoItemCtrl'
})

.controller('TodoItemCtrl', [function() {
  this.test = [1, 2, 3, 4];
}]);

To use $scope see Anurag Srivastava answer. I'm not sure what's the best way, as I have much to learn.

marno11
  • 561
  • 1
  • 5
  • 13