javascript - AngularJS:注入(inject)我的 Controller 有什么问题?

标签 javascript angularjs

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

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

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

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

更好的项目服务:

.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 中使用它:

 .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.
 });

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

关于javascript - AngularJS:注入(inject)我的 Controller 有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29000634/

相关文章:

javascript - 如何根据属性值删除DOM元素

javascript - 通过url找到页面上的图片,并在下面放入数据

javascript - ExtJS TabPanel 在 ViewPort 中缺少滚动条

javascript - 需要 12 小时格式而不显示 AM/PM Timepicker

javascript - 无法让 ng-hide 和 ng-show 工作

javascript - 检测变量更改并执行回调的最有效方法

javascript - Angular JS Controller - 范围问题(可能)

javascript - HTML5 视频/音频播放器使用 AngularJS 控制播放和暂停

angularjs - Angular JS 和 Semantic-UI 复选框需要双击

javascript - KeyboardDatePicker素材ui的语言怎么改?