AngularJS:这个注入我的控制器有什么问题



我正在使用AngularJS构建一个简单的任务管理系统,目前正在使用它并模拟数据。我在将服务注入我的 ProjectCtrl 控制器时遇到问题,我无法理解它。

在此代码的底部:为什么 ProjectsCtrl 控制器中的项目变量只是一个空数组?它应该包含模型数据,不是吗?我做错了什么?

请原谅这个可能非常愚蠢的问题。我只是没有发现我的错误。

angular.module("TaskManager", ['ui.router'])
.config([
    '$stateProvider',
    '$urlRouterProvider',
    function($stateProvider, $urlRouterProvider){
        $stateProvider
            .state('home', {
                url: '/home',
                templateUrl: '/home.html',
                controller: 'MainCtrl'
            })
            .state('projects', {
                url: '/projects/{id}',
                templateUrl: '/projects.html',
                controller: 'ProjectsCtrl'
            });
        $urlRouterProvider.otherwise('home');
    }
])
.factory('projects', [function(){
    var o = {
        projects: []
    };
    return o;
}])
.controller('MainCtrl', [
    '$scope', 
    'projects', 
    function($scope, projects){
        $scope.projects = projects.projects;
        $scope.projects = [
            {title: "project 1", done: 0},
            {title: "Another project 2", done: 0},
            {title: "project 3", done: 1},
            {title: "project 4", done: 0},
            {title: "project 5", done: 0},
        ];
        $scope.addproject = function() {
            if(!$scope.title || $scope.title === '') { return };
            $scope.projects.push({
                title: $scope.title,
                comment: $scope.comment,
                done: 0,
                tasks: [
                    {title: 'Task 1', comment: 'Kommentar 1', done: 0},
                    {title: 'Task 2', comment: 'Kommentar 2', done: 0}
                ]
            });
            $scope.title = "";
            $scope.comment = "";
        }
        $scope.markAsDone = function(project) {
            project.done = 1;
        }
    }
])
.controller('ProjectsCtrl', [
    '$scope',
    '$stateParams',
    'projects', 
    function($scope, $stateParams, projects){
        $scope.project = projects.projects[$stateParams.id];
        // Why is this an empty array?
        console.log(projects);
    }
])

完成:这是 HTML 部分:

<html>
    <head>
        <title>TaskManager</title>
        <link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
    <script src="app.js"></script>
  </head>
  <body ng-app="TaskManager">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
      <ui-view></ui-view>
      </div>
    </div>
    <script type="text/ng-template" id="/home.html">
      <div class="page-header">
        <h1>TaskManager</h1>
        <a href="#/test">TEST</a>
      </div>
      <div ng-repeat="project in projects | orderBy: ['done','title']">
        <span ng-click="markAsDone(project)">Done</span>
        {{project.title}} - done: {{project.done}}
        <span>
          <a href="#/projects/{{$index}}">Tasks</a>
        </span>
        <p ng-show="project.comment">Comment: {{project.comment}}</p>
      </div>
      </hr> 
      <form ng-submit="addproject()" style="margin-top: 30px;">
        <h3>Add new project</h3>
        <input type="text" ng-model="title" placeholder="project"></input>
        <br><br>
        <textarea name="comment" ng-model="comment"></textarea>
        <br>
        <button type="submit" class="btn">Post</button>
      </form>
    </script>
    <script type="text/ng-template" id="/projects.html">
      <div class="page-header">
        <h3>Project: {{project.title}}</h3>
      </div>
      <div ng-repeat="task in project.tasks | orderBy: ['done','title']">
        {{task.title}} - done: {{task.done}}
        <p ng-show="task.comment">Comment: {{task.comment}}</p>
      </div>
    </script>
  </body>
</html>

您永远不会将值分配给projects.projects 。在 MainCtrl 中,您将$scope.projects赋值给 projects.projects(此时为空数组)。然后,您用一个全新的和不同的数组覆盖$scope.projects,因此您永远不会最终修改projects.projects

我会将允许您添加、删除、更新项目的功能移动到projects服务,但在此期间,您可以先分配projects.projects,然后将其分配给$scope.projects

更好的projects服务:

.factory('projects', function() {
  var projects = [];
  return {
     add: function(item) {
        // your additional code
        projects.push(item);
     },
     remove: function(item) {
       // your additional code
       var i = projects.indexOf(item);
       if (i >=0) projects.splice(i,1);
     },
     get: function() {
         return projects;
     },
     initialize: function(items) {
       projects = items;
     }
  };
});

然后,您可以在控制器中使用它:

 .controller('MainCtrl', function($scope, projects) {
    projects.initialize([ ... ]);
    $scope.projects = projects.get();
    $scope.addproject = function() {
        // NOTE: move whatever code you feel is or could be the responsibility of the service to the add method. I left this function as-is though, so you have a frame of reference.
        if(!$scope.title || $scope.title === '') { return };
        projects.add({
            title: $scope.title,
            comment: $scope.comment,
            done: 0,
            tasks: [
                {title: 'Task 1', comment: 'Kommentar 1', done: 0},
                {title: 'Task 2', comment: 'Kommentar 2', done: 0}
            ]
        });
        $scope.title = "";
        $scope.comment = "";
    };
    // etc.
 });

我建议将服务设置为单点授权,以便您可以测试与服务及其数据交互相关的逻辑,并避免在不同的控制器和指令需要与服务或其数据交互时重复自己。它还将帮助您避免数据在不同控制器、指令等之间不同步的此类问题。

当您设置模拟数据时,您只在 $scope.projects 上设置它们...工厂的项目永远不会更新。你可以翻转它,它应该可以工作:

projects.projects = [<mock data>];
$scope.projects = projects.projects;

将模拟数据放在出厂中,并在控制器中删除初始化。

angular.module("TaskManager", ['ui.router'])
.config([
    '$stateProvider',
    '$urlRouterProvider',
    function($stateProvider, $urlRouterProvider){
        $stateProvider
            .state('home', {
                url: '/home',
                templateUrl: '/home.html',
                controller: 'MainCtrl'
            })
            .state('projects', {
                url: '/projects/{id}',
                templateUrl: '/projects.html',
                controller: 'ProjectsCtrl'
            });
        $urlRouterProvider.otherwise('home');
    }
])
.factory('projects', [function(){
 var o = {
         projects: [
            {title: "project 1", done: 0},
            {title: "Another project 2", done: 0},
            {title: "project 3", done: 1},
            {title: "project 4", done: 0},
            {title: "project 5", done: 0},
        ]
    };
    return o;
}])
.controller('MainCtrl', [
    '$scope', 
    'projects', 
    function($scope, projects){
        $scope.projects = projects.projects;

        $scope.addproject = function() {
            if(!$scope.title || $scope.title === '') { return };
            $scope.projects.push({
                title: $scope.title,
                comment: $scope.comment,
                done: 0,
                tasks: [
                    {title: 'Task 1', comment: 'Kommentar 1', done: 0},
                    {title: 'Task 2', comment: 'Kommentar 2', done: 0}
                ]
            });
            $scope.title = "";
            $scope.comment = "";
        }
        $scope.markAsDone = function(project) {
            project.done = 1;
        }
    }
])
.controller('ProjectsCtrl', [
    '$scope',
    '$stateParams',
    'projects', 
    function($scope, $stateParams, projects){
        $scope.project = projects.projects[$stateParams.id];
        // Why is this an empty array?
        console.log(projects);
    }
])

最新更新