2016-12-06 5 views
2

私は時々角の経験を持つ新人のいくつかを明らかに問題を解決しようとしています。私の小さな例では問題を見つけられなかったいくつかの記事があります。シナリオ:

  • コメントを表示するウェブページ&評価。
  • サイトはJavaScriptを既存のコメントが
  • の配列に新しいエントリを簡単に全体的な話のために1コントローラー可能性がプッシュする必要がありますが、それはするつもりだった
  • 新しいコメント/評価を入力する可能性を提供コントローラの「継承」モデルについて学ぶので、2つの小さなコントローラ

問題意思であります。

  • 新しいエントリトンをプッシュ(コントローラ2での)関数は、 o の配列(Controller 1)は、このスコープ内の配列が未定義であるため、TypeErrorになります。

'use strict'; 
 

 
angular.module('confusionApp', []) 
 

 
     .controller('DataController', ['$scope', function($scope) { 
 
      $scope.comments = [{rating: 1, comment:"bla", author: "pma", date: new Date().toISOString()} , {rating:2, comment:"harakiri", author:"hku", date: new Date().toISOString()}]; 
 
     }]) 
 

 
     .controller('CommentController', ['$scope', function($scope) { 
 

 
      $scope.comment = {rating:5, comment:"", author:"", date: new Date().toISOString() }; 
 

 
      $scope.submitComment = function() { 
 
       console.log($scope.comment); 
 
       $scope.comment.date = new Date().toISOString(); 
 

 
       // this scope here does not know about the comments array --> BUG     
 
       $scope.comments.push($scope.comment); 
 
       $scope.commentForm.$setPristine(); 
 
       $scope.comment = {rating:5, comment:"", author:"", date: new Date().toISOString()}; 
 
       console.log($scope.comment); 
 
      }; 
 
     }]) 
 

 
;

HTMLページ

<!DOCTYPE html> 
 
<html lang="en" ng-app="confusionApp"> 
 

 
<head> 
 
    <meta charset="utf-8"> 
 
    <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
 
    <!-- The above 3 meta tags *must* come first in the head; any other head 
 
     content must come *after* these tags --> 
 
    <title>Ristorante Con Fusion: Menu</title> 
 
     <!-- Bootstrap --> 
 
<!-- build:css styles/main.css --> 
 
    <link href="../bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"> 
 
    <link href="../bower_components/bootstrap/dist/css/bootstrap-theme.min.css" rel="stylesheet"> 
 
    <link href="../bower_components/font-awesome/css/font-awesome.min.css" rel="stylesheet"> 
 
    <link href="styles/bootstrap-social.css" rel="stylesheet"> 
 
    <link href="styles/mystyles.css" rel="stylesheet"> 
 
<!-- endbuild --> 
 

 
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> 
 
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> 
 
    <!--[if lt IE 9]> 
 
     <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> 
 
     <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> 
 
    <![endif]--> 
 
</head> 
 

 
<body> 
 
    <div class="container"> 
 
     <div class="row row-content"> 
 
      <div class="col-xs-12"> 
 
       <div class="row row-content" ng-controller="DataController"> 
 
        <div class="col-xs-9 col-xs-offset-1"> 
 
         <blockquote ng-repeat="comment in comments | orderBy: sortOption"> 
 
         <p>{{comment.rating}} Stars</p> 
 
         <p>{{comment.comment}}</p> 
 
         <footer>{{comment.author}}, {{comment.date | date}}</footer> 
 
         </blockquote> 
 
        </div> 
 
      </div> 
 
      <div class="col-xs-9 col-xs-offset-1" ng-controller="CommentController"> 
 
       <form class="form-horizontal" name="commentForm" ng-submit="submitComment()" novalidate> 
 
        <!-- name property --> 
 
        <div class="form-group" ng-class="{ 'has-error' : commentForm.author.$error.required || commentForm.author.$pristine }"> 
 
         <label for="name" class="col-sm-2 control-label">Name</label> 
 
         <div class="col-sm-10"> 
 
         <input type="text" class="form-control" id="author" name="author" placeholder="Enter your name" ng-model="comment.author" required> 
 
         <span ng-show="commentForm.author.$error.required || commentForm.author.$pristine" class="help-block">Your name is required</span> 
 
         </div> 
 
        </div> 
 
        <!-- the rating --> 
 
        <div class="form-group"> 
 
        <label for="rating" class="col-sm-2 control-label">Rating</label> 
 
        <div class="col-sm-10"> 
 
         <label class="radio-inline"> 
 
          <input type="radio" name="ratingGroup" id="inlineRadio1" ng-model="comment.rating" value="1"> 1 
 
         </label> 
 
         <label class="radio-inline"> 
 
          <input type="radio" name="ratingGroup" id="inlineRadio1" ng-model="comment.rating" value="2"> 2 
 
         </label> 
 
         <label class="radio-inline"> 
 
          <input type="radio" name="ratingGroup" id="inlineRadio1" ng-model="comment.rating" value="3"> 3 
 
         </label> 
 
         <label class="radio-inline"> 
 
          <input type="radio" name="ratingGroup" id="inlineRadio1" ng-model="comment.rating" value="4"> 4 
 
         </label> 
 
         <label class="radio-inline"> 
 
          <input type="radio" name="ratingGroup" id="inlineRadio1" ng-model="comment.rating" value="5"> 5 
 
         </label> 
 
        </div> 
 
        </div> 
 
        <!-- the comments --> 
 
        <div class="form-group" ng-class="{ 'has-error' : commentForm.comment.$error.required || commentForm.comment.$pristine }"> 
 
         <label for="feedback" class="col-sm-2 control-label">Your Comment</label> 
 
         <div class="col-sm-10"> 
 
          <textarea class="form-control" id="comment" name="comment" rows="12" ng-model="comment.comment" placeholder="Please provide some comments" required></textarea> 
 
          <span ng-show="commentForm.comment.$error.required || commentForm.comment.$pristine" class="help-block">Your comment is required !</span> 
 
         </div> 
 
        </div> 
 
        <!-- the button --> 
 
        <div class="form-group"> 
 
         <div class="col-sm-offset-2 col-sm-10"> 
 
          <button type="submit" class="btn btn-primary" ng-disabled="commentForm.$invalid">Send Comments</button> 
 
         </div> 
 
        </div> 
 
       </form> 
 
      </div> 
 
     </div> 
 
    </div> 
 

 
<!-- build:js scripts/main.js --> 
 
    <script src="../bower_components/angular/angular.min.js"></script> 
 
    <script src="scripts/app.js"></script> 
 
<!-- endbuild --> 
 

 
</body> 
 

 
</html>

任意のヒントをいただければ幸いです、ありがとうございました。

+0

一つの方法は、$放送サービスを使用して最初のコントローラに2番目のコントローラにコメントしてイベントをブロードキャストすることである(これはにブロードキャストあなたの最初のコントローラに$ onイベントを登録して、ブロードキャストされたイベントをチェックしてください。 –

答えて

1

通常、表示あたり1つのコントローラはです。 DataControllerとCommentControllerという2つのコントローラが同じビューにあります。

配列はサービスに格納する必要があります(両方のコントローラに挿入します; CommentControllerはサービスの配列にコメントを追加します; DataControllerはそこから読み取ります)。

ng-click(CommentController)が通常DataControllerで使用される配列をリフレッシュするイベントをトリガーすると、状況が複雑になります。

適切な方法は、コントローラを1つだけ使用することです。ここで

は、私は、配列のためにサービスを設定する方法である:

.service('CommentService', function() { 
    var comments = [ 
    {rating: 1, comment:"bla", author: "pma", date: new Date()}, 
    {rating:2, comment:"harakiri", author:"hku", date: new Date()} 
    ]; 

    return { 
    comments: comments 
    } 
}) 

http://codepen.io/nadeemramsing/pen/QGmzbV?editors=1111
(ただしソリューション不完全;ただ一つのコントローラーを使用)

+0

ありがとうございます!クール。 –

1

あなたは、コントローラのスコープを継承について学びたいです。あなたの例で間違っているところは、CommentControllerは実際にDataControllerの子コントローラではないため、スコープを継承しないということです。

したがって、HTMLではDataControllerがCommentControllerの親であることを確認する必要があります。これを達成するための簡単な方法body要素にDataControllerを移動することです:あなたが行うことができます

<body ng-controller="DataController"> 
+0

ありがとう、クール! –

関連する問題