有没有办法利用那里的双向通信? (例如,从 postComment 中完成的 AJAX 调用中添加 errmsg 字段或在提交时清除表单?)
我建议一个带有自己控制器的指令。通过这种方法,comment 模型被封装在指令中。该指令需要两条信息: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>
我个人还没有决定自定义指令应该走多远。我会对人们对此的任何 cmets 非常感兴趣。