0

AngularJSでブログのインデックスページを作成している場合、次のようなコメントがあります。

<li ng-repeat="post in posts">
    <h2>{{post.title}}
    <p>{{post.description}}</p>
    <h3>Leave a comment</h3>
    <form ng-submit="postComment()">
       <input type="hidden" value="{{post.id}}">
       Name: <input type="text"> <br>
       Comment: <textarea></textarea> <br>
       <input type="submit" value="Post comment">
    </form>
</li>

postComment()モデルをフォームに関連付けてコントローラーの機能からアクセスするのが正しい方法がわかりません。すべてのフォームに1つのモデルだけを使用する場合、1つの投稿にコメントを残し始めると、すべてのフォームにコメントを残し始めます。ただし、非表示のpost.idフィールドで奇妙なことをしている場合を除きますが、それは一風変わった感じになります。

4

2 に答える 2

2

オブジェクトを関数呼び出しに渡すことができます。

<form ng-submit="postComment(post.id)">

他の入力に関しては、実際には状況によって異なりますが、この場合、inputtextareaは、の中にありngRepeat、新しいスコープを作成します。そのため、スコープの値を割り当てても、ページの他の要素には影響しません。

<li ng-repeat="post in posts">
    <h2>{{post.title}}
    <p>{{post.description}}</p>
    <h3>Leave a comment</h3>
    <form ng-submit="postComment(post.id, commentName, commentText)">
       Name: <input type="text" ng-model="commentName"> <br>
       Comment: <textarea ng-model="commentText"></textarea> <br>
       <input type="submit" value="Post comment">
    </form>
</li>
于 2013-02-03T01:02:50.873 に答える
1

そこで双方向通信を利用する方法はありますか?(たとえば、postCommentで行われたAJAX呼び出しからerrmsgフィールドを追加するか、送信時にフォームをクリアしますか?)

独自のコントローラーを備えたディレクティブをお勧めします。このアプローチでは、commentモデルはディレクティブにカプセル化されます。ディレクティブには2つの情報が必要です。1)postID 2)コメントを保存するために呼び出す関数。サーバーから返されたエラーメッセージの表示をサポートするために、コメントとともにコールバック関数が渡されます。これにより、コントローラーは、保存操作の試行後に必要になる可能性のあるエラーメッセージやその他の情報をディレクティブにフィードできます。

app.directive('commentForm', function() {
  var template = '<form name="commentForm" '
    + 'ng-submit="save({comment: comment, callbackFn: callbackFn})">'
    + '<h3>Leave a comment</h3>'
    + 'Name: <input type="text" ng-model="comment.name" name="commentName"> <br>'
    + '<span class="error" ng-show="commentForm.commentName.$error.myError">Error</span><br>'
    + 'Comment: <textarea ng-model="comment.text"></textarea> <br>'
    + '<input type="submit" value="Save comment">'
    + '</form>';
  return {
    restrict: 'E',
    template: template,
    scope: { postId: '@', save: '&' },
    controller: function($scope) {
      $scope.callbackFn = function(args) {
        console.log('callback', args);
        if(args.error.name) {
          $scope.commentForm.commentName.$setValidity("myError", false);
        } else {
          // clear form
          $scope.comment.name = '';
          $scope.comment.text = '';
        }
      };
    }
  };
});


app.controller('MainCtrl', function($scope, $timeout) {
  $scope.post = {id: 1};
  $scope.saveComment = function(comment, callbackFn) {
    console.log('saving...', comment);
    // Call $http here... then call the callback.
    // We'll simulate doing something with a timeout.
    $timeout(function() {
      if(comment.name === "name") {
        callbackFn( {error: {name: 'try again'}} );
      } else {
        callbackFn( {error: {}} );
      }
   }, 1500)
  }
});

次のように使用します。

<comment-form post-id="{{post.id}}" save="saveComment(comment, callbackFn)"></comment-form>

'&'構文に関連するやや奇妙な構文に注意してください。ディレクティブがHTMLで使用される場合、saveComment()関数の引数を指定します。ディレクティブ/テンプレートでは、オブジェクト/マップを使用して、各引数名をその値に関連付けます。値はローカル/ディレクティブスコーププロパティです。

Plnkr。plnkrでは、1.5秒の$timeoutを使用してAJAX投稿をシミュレートしました。名前のテキストボックスに入力nameして[保存]ボタンをクリックすると、1.5秒でエラーが発生します。それ以外の場合、フォームは1.5秒後にクリアされます。

これをどこまで進めたいかに応じて...投稿テンプレートをディレクティブにカプセル化することもできます。

<li ng-repeat="post in posts">
   <post=post></post>
   <comment-form ...></comment-form>
</li>

コメントフォームをpostディレクティブテンプレート内に配置して、HTMLをさらに単純化することもできます。

<li ng-repeat="post in posts">
   <post=post></post>
</li>

post-listディレクティブを使用することもでき、そのテンプレートにはng-repeatが含まれ、HTMLを単一の要素に縮小します。

<post-list posts=posts></post-list>

個人的には、カスタムディレクティブをどこまで使用するかはまだ決めていません。私は人々がこれについて持っているどんなコメントにも非常に興味があります。

于 2013-02-03T04:55:59.053 に答える