2015-11-07 100 views
0

所以我跟着thinkster.io MEAN stack tutorial一直跟着我完成了一切,直到“开始节点”,但我的应用程序没有按预期工作。AngularJS工厂不工作?

查看帖子的评论时,似乎工厂没有正确分享其变量。标题(和链接,如果存在于该帖子记录中)不显示,也不显示评论(如果该帖子记录具有相关评论)。

我已经查看了我的代码几次,并确保它遵循教程,但我无法让它工作!我究竟做错了什么?

indexV2.html

<html> 
    <head> 
    <title>My Angular App!</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.3.10/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="appV3.js"></script> 
    <style> .glyphicon-thumbs-up { cursor:pointer } </style> 
    </head> 
<body ng-app="flapperNews"> 
    <div class="container"> 
    <div class="row"> 
     <div class="col-md-6 col-md-offset-3"> 

     <!-- where ui-router places templates, depending on the state --> 
     <ui-view></ui-view> 

     </div> 
    </div> 
    </div> 
    </div> 

    <script type="text/ng-template" id="/home.html"> 
    <!-- begin home.html inline template --> 
    <div class="page-header"> 
     <h1>Flapper News</h1> 
    </div> 

    <form ng-submit="addPostV2()"> 
     <div class="form-group"> 
     <input class="form-control" type="text" placeholder="Title" ng-model="title"></input> 
     </div> 
     <div class="form-group"> 
     <input class="form-control" type="text" placeholder="Link" ng-model="link"></input> 
     </div> 
     <button type="submit" class="btn btn-primary">Add Post</button> 
    </form> 

    <div ng-repeat="post in posts | orderBy: '-upvotes'"> 
     <span class="glyphicon glyphicon-thumbs-up" ng-click="incrementUpvotes(post)"></span> 
     <a href="{{post.link}}" ng-show="post.link">{{post.title}}</a> 
     <span ng-hide="post.link">{{post.title}}</span> 
     - upvotes: {{post.upvotes}} 
     - <span> 
     <a href="#/posts/{{$index}}">Comments</a> 
     </span> 
    </div> 
    </script> 

    <script type="text/ng-template" id="/posts.html"> 
     <!-- begin posts.html inline template --> 
     <div class="page-header"> 
     <h3> 
      <a ng-show="post.link" href="{{post.link}}"> 
      {{post.title}} 
      </a> 
      <span ng-hide="post.link"> 
      {{post.title}} 
      </span> 
     </h3> 
     </div> 

     <div ng-repeat="comment in post.comments | orderBy:'-upvotes'"> 
     <span class="glyphicon glyphicon-thumbs-up" ng-click="incrementUpvotes(comment)"></span> 
      {{comment.upvotes}} - by {{comment.author}} 
     <span style="font-size:20px; margin-left:10px;"> 
      {{comment.body}} 
     </span> 
     </div> 

     <form ng-submit="addComment()" style="margin-top:30px;"> 
     <h3>Add a new comment</h3> 
     <div class="form-group"> 
      <input type="text" class="form-control" placeholder="Comment" ng-model="body"></input> 
     </div> 
     <button type="submit" class="btn btn-primary">Post</button> 
     </form> 
    </script> 

    </body> 
</html> 

appV3.js

// instantiate app, call it flapperNews, and declare the ui.router dependency 
var app = angular.module('flapperNews', ['ui.router']); 

// Set up states using the config function 
app.config([ 
    '$stateProvider', 
    '$urlRouterProvider', 
    function($stateProvider, $urlRouterProvider) { 
     $stateProvider 
      .state('home', { // homepage state 
       url: '/home', 
       templateUrl: '/home.html', // specify template (will be inline, in index.html, for this example) 
       controller: 'MainCtrl' // assign a controller 
      }) 
      .state('posts', { // state that will display comments associated with a post 
       url: '/posts/{id}', // id is a route parameter, made available to our controller 
       templateUrl: '/posts.html', 
       controller: 'PostsCtrl' 
      }); 
     $urlRouterProvider.otherwise('home'); // redirect unspecified routes 
    } 
]); 

// factory that will share the posts array with controllers 
app.factory('posts', [function() { 
    var o = { // create object that will hold our posts array 
     posts: [] 
    }; 
    return o; 
}]); 

// controller for "home" state 
app.controller('MainCtrl', [ 
    '$scope', 
    'posts', // inject service into controller (by adding it as a parameter) 
    function($scope, posts) { 

     // bind (not just assign) the service variable to our scope 
      // any changes in either will be reflected in the other 
     $scope.posts = posts.posts; 

     $scope.posts = [ // array of objects 
      {title: 'post 1', upvotes: 3, url: ''}, // object (collection of properties) with 2 properties 
      {title: 'post 2', upvotes: 4, url: ''}, 
      {title: 'post 3', upvotes: 1, url: ''}, 
      {title: 'post 4', upvotes: 2, url: ''}, 
      {title: 'post 5', upvotes: 6, url: ''} 
     ]; 

     $scope.addPostV2 = function() { 
      if(!$scope.title || $scope.title === '') { // if empty or not set 
       return;         // exit function 
      } 
      $scope.posts.push({ // push new object into array 
       title: $scope.title, 
       link: $scope.link, 
       upvotes: 0, 
       comments: [ // fake array 
        {author: 'Joe', body: 'Cool post!', upvotes: 0}, 
        {author: 'Bob', body: 'Great idea but everything is wrong!', upvotes: 0} 
       ] 
      }); 
      $scope.title = ''; // empty the property (the model in the form) 
      $scope.link = ''; 
     } 

     $scope.incrementUpvotes = function(post) { // pass the instance of post (passed in calling function, by reference - located in HTML) 
      post.upvotes += 1; 
     } 

    } 
]); 

// new controller for "posts" state 
app.controller('PostsCtrl', [ 
    '$scope', 
    '$stateParams', 
    'posts', 
    function($scope, $stateParams, posts) { 

     $scope.post = posts.posts[$stateParams.id]; // Grab a post from posts, using the id parameter from $stateParams (in URL) 

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

     $scope.incrementUpvotes = function(comment) { 
      comment.upvotes += 1; 
     } 
    } 
]); 

感谢您的帮助提前

+0

什么不工作? – Sajeetharan

+0

我道歉@Sajeetharan,我在第二段中给我的问题添加了更多细节。实际上,虽然home.html模板可以正确引用posts对象并在模板中显示其属性,但posts.html模板不能。 – CFitz

回答

2

让我们来看看你的代码:

$scope.posts = posts.posts; 

这行代码后,这里就是你拥有的一切:

posts.posts -------> [] 
        ^
$scope.posts --------| 

因此,无论$ scope.posts和posts.posts引用的是相同的,空数组。

现在下面的行:

$scope.posts = [ // array of objects 
    {title: 'post 1', upvotes: 3, url: ''}, 
    ... 
]; 

这行不填充由所述服务和范围引用的数组。它为$ scope.posts分配一个新的数组。所以,你最终

posts.posts -------> [] 

$scope.posts ------> [{title: 'post 1', upvotes: 3, url: ''}, ...] 

所以,当你去到下一个屏幕,并取回从posts.posts元素:

$scope.post = posts.posts[$stateParams.id]; 

你回来什么都没有,因为posts.posts仍原来的空阵列。

而不是

$scope.posts = [ // array of objects 
    {title: 'post 1', upvotes: 3, url: ''}, 
    ... 
]; 

你需要

$scope.posts.push({title: 'post 1', upvotes: 3, url: ''}); 
... 

然后,你将填补由控制器和由服务所引用的数组。

请注意,使详细信息页面依赖于列表页面,因此无论如何这是一个糟糕的主意:如果用户刷新详细信息页面,应用程序将从头开始,而详细信息页面将不会找到任何内容阵列。你应该通过向服务器发送GET请求来获得帖子。

+0

谢谢,这工作!当我想到'范围'时我错了。我们可以将这些对象添加到现有的数组中(而不是指向一个新的数组),而不是指向一个新的数组。 ,空阵列 - 这实际上是它做的。感谢您的澄清 - 我非常感谢! – CFitz