AngularJS 在一个控制器中显示 2 个模型

AngularJS show 2 models in one controller

我有 2 个模型(项目和任务)要显示在我的 home.html 中,我希望它们像这样显示:http://plnkr.co/edit/ItNvBNBIrLxqwRrhye5p,其中显示和过滤数据范围基于相同的颜色。

我使用 Angular 控制器 (projectCtrl.js) 来控制我网页上的数据 (home.html),并使用 Angular 服务 (projectService.js) 从我用 express 框架和 mongoose 编写的 api 文件 (api.js) 中获取数据。

但是我的代码没有显示任何内容,所以我不知道哪里出了问题。

home.html:

<div class="row" ng-if="main.loggedIn">
  <div ng-controller="ProjectController">
    <div class="panel col-md-8">
      <!-- Project heading setup -->
      <div class="panel-group" ng-repeat="eachProject in project.projects | reverse track by $index">
        <div class="panel panel-info">
          <div class="panel-heading" data-toggle="collapse" ng-click="true" data-target="#projectDetails{{$index}}" href="#projectDetails{{$index}}">
            <h4>{{eachProject.title}}: {{eachProject.short_description}}</h4>
          </div>
          <div class="panel-collapse collapse out" id="projectDetails{{$index}}">
            <p class="panel-body">
              <!-- Project detail table, where project data displays-->
              <table class="table table-responsive table-bordered table-hover">
                <tr>
                  <th>Description: </th>
                  <td>{{eachProject.description}}</td>
                </tr>
              </table>

              <!-- Task heading setup -->
              <div class="panel-group" ng-repeat="eachTask in task.tasks | filter: { projectID: eachProject.id }">
                <div class="panel panel-success">
                  <div class="panel-heading" data-toggle="collapse" ng-click="true" data-target="#taskDetails{{$index}}" href="#taskDetails{{$index}}">
                    <h5>{{eachTask.title}}</h5>
                  </div>
                  <div class="panel-collapse collapse out" id="taskDetails{{$index}}">
                    <p class="panel-body">
                      <!-- Task detail table, where tasks data displays -->
                      <table class="table table-responsive table-bordered table-hover">
                        <tr>
                          <th>Description: </th>
                          <td>{{eachTask.description}}</td>
                        </tr>
                      </table>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

ProjectCtrl.js

angular.module('projectCtrl', ['projectService'])

.controller('ProjectController', function(Project, Task, socketio) {
  var vm = this;
  Project.all()
  .success(function(data) {
    vm.projects = data;
  })

  vm.createProject = function() {
    // Wrong due date prevention
    var start = new Date(vm.projectData.start_date);
    var due = new Date(vm.projectData.due_date);
    if (start > due) {
      alert("Due date can't be earlier than start date, please decide a new due date.");
      return;
    }
    // Create project
    vm.message = '';
    Project.create(vm.projectData)
    .success(function(data) {
      // Clear up the project
      vm.projectData = '';
      vm.message = data.message;
      $('#createProject').modal('hide');
    })
  }

  Task.all()
  .success(function(data) {
    vm.tasks = data;
  })

  vm.createTask = function() {
    // Wrong due date prevention
    var start = new Date(vm.taskData.taskStart_date);
    var due = new Date(vm.taskData.taskDue_date);
    if (start > due) {
      alert("Due date can't be earlier than start date, please decide a new due date.");
      return;
    }
    // Create task
    vm.message = '';
    Task.create(vm.taskData)
    .success(function(data) {
      // Clear up the task
      vm.taskData = '';
      vm.message = data.message;
      $('#createTask').modal('hide');
    })
  }

  socketio.on('project', 'task', function(data) {
    vm.projects.push(data);
    vm.tasks.push(data);
  })

})

.controller('AllProjectsController', function(projects, socketio) {
  var vm = this;
  vm.projects = projects.data;

  socketio.on('project', function(data) {
    vm.projects.push(data);
  })
})

projectService.js

angular.module('projectService', [])

.factory('Project', function($http) {
  var projectFactory = {};
  projectFactory.create = function(projectData) {
    return $http.post('/api', projectData);
  }
  projectFactory.allProjects = function() {
    return $http.get('/api/all_projects');
  }
  projectFactory.all = function() {
    return $http.get('/api');
  }
  projectFactory.deleteProject = function(id) {
    return $http.post('/api/deleteProject', {id: id});
  }
  return projectFactory;
})

.factory('Task', function($http) {
  var taskFactory = {};
  taskFactory.create = function(taskData) {
    return $http.post('/api', taskData);
  }
  taskFactory.allTasks = function() {
    return $http.get('/api/all_tasks');
  }
  taskFactory.all = function() {
    return $http.get('/api');
  }
  taskFactory.deleteTask = function(id) {
    return $http.post('/api/deleteTask', {projectID: id});
  }
  return taskFactory;
})

.factory('socketio', function($rootScope) {
  var socket = io.connect();
  return {
    on: function(eventName, callback) {
          socket.on(eventName, function() {
            var args = arguments;
            $rootScope.$apply(function() {
              callback.apply(socket, args);
            })
          })
    },

    emit: function(eventName, data, callback) {
      socket.emit(eventName, data, function() {
        var args = arguments;
        $rootScope.apply(function() {
          if(callback) {
            callback.apply(socket, args);
          }
        })
      })
    }
  }
})

api.js

var User = require('../models/user');
var Project = require('../models/project');
var config = require('../../config');
var secretKey = config.secretKey;
var jsonwebtoken = require('jsonwebtoken');
var fields = '...'; // a lot of fields, deleted them just to make it short

// Create tokens for users with jsonwebtoken
function createToken(user) {
  var token = jsonwebtoken.sign({
    id: user._id,
    firstname: user.firstname,
    lastname: user.lastname,
    username: user.username
  }, secretKey, {
    expirtesInMinute: 1440
  });
  return token;
}

module.exports = function(app, express, io) {
  var api = express.Router();

  api.get('/all_projects', function(req, res) {
    Project.find({}, function(err, projects) {
      if (err) {
        res.send(err);
        return;
      }
      res.json(projects);
    })
  })

  // login api
  api.post('/login', function(req, res) {
    User.findOne({
      username: req.body.username
    }).select(fields).exec(function(err, user) {
      if(err) {
        throw err;
      }
      if (!user) {
        res.send({ message: "User doesn't exist"});
      } else if(user){
        var validPassword = user.comparePassword(req.body.password);
        if (!validPassword) {
          res.send({ message: "Invalid Password"});
        } else {
          var token = createToken(user);
          res.json({
            success: true,
            message: "Login Successfully !",
            token: token
          });
        }
      }
    });
  });

  //middleware
  api.use(function(req, res, next) {
    console.log("Somebody just logged in!");
    var token = req.body.token || req.param('token') || req.headers['x-access-token'];
    if (token) {
      jsonwebtoken.verify(token, secretKey, function(err, decoded) {
        if (err) {
          res.status(403).send({success: false, message: "Failed to authenticate user."});
        } else {
          req.decoded = decoded;
          next();
        }
      });
    } else {
      res.status(403).send({ success: false, message: "No Token Provided." });
    }
  });

  //api for projects handling
  api.route('/')
  .post(function(req, res) {
    var project = new Project({
      creatorID: req.decoded.id,
      creator: req.decoded.firstname + " " + req.decoded.lastname,
      creator_dept: req.decoded.department,
      title: req.body.title,
      short_description: req.body.short_description,
      description: req.body.description,
      priority: req.body.priority,
      status: calcStatus(),
      assign_dept: req.body.assign_dept,
      estimate_cost: req.body.estimate_cost,
      actual_cost: req.body.actual_cost,
      last_modified_date: req.body.last_modified_date,
      due_date: req.body.due_date,
      start_date: req.body.start_date,
      complete_date: req.body.complete_date,
    });
    project.save(function(err, newProject) {
      if (err) {
        res.send(err);
        return;
      }
      io.emit('project', newProject);
      res.json({
        message: "New Project Created!"
      });
    });
  })
  .get(function(req, res) {
    Project.find( {creatorID: req.decoded.id}, function(err, project) {
      if (err) {
        res.send(err);
        return;
      }
      res.json(project);
    });
  });

  //api for tasks handling
  api.route('/')
  .post(function(req, res) {
    var task = new Task({
      creatorID: req.decoded.id,
      creator: req.decoded.firstname + " " + req.decoded.lastname,
      projectID: req.body.taskProjectID,
      title: req.body.taskTitle,
      description: req.body.taskDescription,
      status: calcStatus(),
      assigneeName: req.body.assigneeName,
      assigneeID: req.body.assigneeID,
      assignee_dept: req.body.assignee_dept,
      estimate_cost: req.body.taskEstimate_cost,
      actual_cost: req.body.TaskActual_cost,
      last_modified_date: req.body.taskLast_modified_date,
      due_date: req.body.taskDue_date,
      start_date: req.body.taskStart_date,
      complete_date: req.body.taskComplete_date,
    });
    task.save(function(err, newTask) {
      if (err) {
        res.send(err);
        return;
      }
      io.emit('tasks', newTask);
      res.json({
        message: "New Task Created!"
      });
    });
  })
  .get(function(req, res) {
    Task.find( {projectID: req.decoded.id}, function(err, task) {
      if (err) {
        res.send(err);
        return;
      }
      res.json(task);
    });
  });
  // api for angular
  api.get('/me', function(req, res) {
    res.json(req.decoded);
  });
  return api;
}

感谢您的帮助。

您在此处引用 project.projects:

<div class="panel-group" ng-repeat="eachProject in project.projects | reverse track by $index">

但是 project 永远不会出现在 ProjectController 中...我想你可能想设置 project 来引用你的 ProjectController,试试这个:

<div ng-controller="ProjectController as project">

编辑

其他一些问题。您提到您也想显示所有任务,在 ProjectController 中,您像这样填充项目和任务:

Project.all()
  .success(function(data) {
    vm.projects = data;
  })
....
Task.all()
  .success(function(data) {
    vm.tasks = data;
  })

很好,除了 Project.all 和 Task.all 的定义引用相同的数据源:

  projectFactory.all = function() {
    return $http.get('/api');
  }

  taskFactory.all = function() {
    return $http.get('/api');
  }

他们都引用了 /api。他们怎么能期望来自同一条路线的不同数据呢?它们应该是两条截然不同的路线。

此外,您在 api.js 中对此端点的定义需要传递一个 ID 才能获得单个项目:

.get(function(req, res) {
    Task.find( {projectID: req.decoded.id}, function(err, task) {
      if (err) {
        res.send(err);
        return;
      }
      res.json(task);
    });
  });

 .get(function(req, res) {
    // The request must contain a creatorId, otherwise you're not going to find your project
    Project.find( {creatorID: req.decoded.id}, function(err, project) {
      if (err) {
        res.send(err);
        return;
      }
      res.json(project);
    });
  });

也许您的 projectService 应该指向 /all_projects 端点而不是 .all。总结一下:

  1. API Project/Task 的终点应该不同
  2. 如有必要,请务必通过项目 ID/task,否则您将无法获得预期的数据。
  3. 设置断点和日志输出以跟踪您的代码路径以查看其他错误可能出在哪里。