TypeError:无法使用Angular读取undefined的属性'comments'

时间:2015-08-12 11:35:31

标签: angularjs

I'm following this tutorial当我尝试在帖子上发表评论时,我的控制台出现TypeError: Cannot read property 'comments' of undefined错误。

mainCtrl,

.controller('mainCtrl', ['$scope', 'posts',
  function($scope, posts){
    $scope.posts = posts.posts;

  $scope.addPost = function(){
    if(!$scope.title || $scope.title === '') { alert("Field can't left blank"); return; }

    $scope.posts.push({
      title: $scope.title,
      upvotes: 0,
      comments: [
        {author: 'Joe', body: 'Cool post!', upvotes: 0},
        {author: 'Bob', body: 'Great idea but everything is wrong!', upvotes: 0}
      ]
    });
  };
  }
])

和postCtrl,

.controller('PostsCtrl', ['$scope', '$stateParams', 'posts',
  function($scope, $stateParams, posts){
    $scope.post = posts.posts[$stateParams.id];

    $scope.addComment = function(){
      if($scope.body === '') { return; }
      $scope.post.comments.push({
        body: $scope.body,
        author: 'user',
        upvotes: 0
      });
      $scope.body = '';
    };

  }
])

两个控制器都在mainCtrl.js

这是我的home.html和post.html部分,它们通过router-ui包含。

%script{:id => "/home.html", :type => "text/ng-template"}
  %h1
    Flappernews

  %a{:href => "#/posts/{{$index}}"} Comments

%script{:id => "/posts.html", :type => "text/ng-template"}
  %h2
    Below here should be comments
  %span
    {{ post.comments }}
  %div{"ng-repeat" => "comment in post.comments | orderBy:'-upvotes'"}
    {{comment.upvotes}} - by {{comment.author}}
    %span{:style => "font-size:20px; margin-left:10px;"}
      {{comment.body}}

  %form{"ng-submit" => "addComment()"}
    %h3 Add a new comment
    .form-group
      %input.form-control{"ng-model" => "body", :placeholder => "Comment", :type => "text"}
    %button.btn.btn-primary{:type => "submit"} Post

当我访问主页时,我被重定向到localhost:3000/#/home我可以输入标题并发布。当我点击comments链接时,我会被重定向到http://localhost:3000/#/posts/,当我尝试发表评论时,我会得到

TypeError: Cannot read property 'comments' of undefined at Scope.$scope.addComment错误。

4 个答案:

答案 0 :(得分:1)

您已经定义了两个独立的控制器,不需要这样做。如果再次查看该教程,您将看到addPost和addComment函数位于单个控制器中,如此

   .controller('PostsCtrl', [
    '$scope',
    '$stateParams',
    'posts',
    function($scope, $stateParams, posts){

    // Fetch post object from state parameter.
    $scope.post = posts.posts[$stateParams.id];

    // Add Post.
    $scope.posts.push({
      title: $scope.title,
      link: $scope.link,
      upvotes: 0,
      comments: [
        {author: 'Joe', body: 'Cool post!', upvotes: 0},
        {author: 'Bob', body: 'Great idea but everything is wrong!', upvotes: 0}
      ]
    });

    // Add comment.
    $scope.addComment = function(){
      if($scope.body === '') { return; }
      $scope.post.comments.push({
        body: $scope.body,
        author: 'user',
        upvotes: 0
      });
      $scope.body = '';
    };

    }]);

在单个Post对象上添加帖子和评论作品,其中预定义了comments属性。

答案 1 :(得分:0)

我确信存在参考链接问题。 $ scope.posts = posts.posts;只应该用来访问posts对象。 CURD操作应该直接在服务上执行。

$ scope.posts将自动更改,因为$ scope.posts和帖子之间存在引用链接。

请在下方进行更改。希望它能起作用。

    $scope.addPost = function () {
      if (!$scope.title || $scope.title === '') {
          alert("Field can't left blank");
          return;
      }

      posts.posts.push({
          title: $scope.title,
          upvotes: 0,
          comments: [{
              author: 'Joe',
              body: 'Cool post!',
              upvotes: 0
          }, {
              author: 'Bob',
              body: 'Great idea but everything is wrong!',
              upvotes: 0
          }]
      });
  };

现在您可以在不同的控制器之间共享数据。添加评论时也应该这样做。

重要部分:

你不能像posts.posts [$ stateParams.id]那样发帖;这将匹配数组的索引并返回对象。

angular.forEach(posts.posts, function (post) {
    if (post.id === parseInt($stateParams.id)) {
        $scope.post = post;
        return;
    }

})

希望这会对你有所帮助。

答案 2 :(得分:0)

在您的' mainCrtl'中,您没有保存/添加新的帖子数据到您的帖子'对象但添加到' $ scope.posts'所以它会在你的页面中反映评论链接(让我们说你新创建的帖子ID是' x')。

当您点击评论链接时,并尝试检查之前未添加的数据到您的帖子中。对象ie ..,posts [x]未定义(你没有在maincrtl中添加id' x'数据)。

希望我已经回答了你的问题。

答案 3 :(得分:0)

由于我无法调试代码,因此我将尝试列出所有可能的原因,您可以确认哪种情况适用于您的情况

  1. 确保新帖子已正确推送到posts服务。
  2. $scope.posts.push之后放置一个断点并记录posts.posts以确保将新对象添加到数组中

    1. 确保PostsCtrl具有相同的posts.posts数组并添加新帖子。

    2. 确保$stateParams.id实际上是posts.posts数组的有效索引

    3. 我希望这会有所帮助。如果没有,请对结果发表评论。