2015-11-07 102 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