Reputation: 552
I'm pretty new to AngularJS, and in my inquisitive nature have attempted (and succeeded in most respects) in writing a news page, that allows users to comment on each article.
What I'm totally unhappy with though is my use of classic Javascript to get the story from the forms dynamically; you can see that I'm creating input fields that I am using a GetElementById
on. Is there anyway to tidy this up with the two way data binding? I originally did this, but my lack of knowledge meant that the model was bound to BOTH forms; what would the the 'Angular' way around this? Primarily I can see that the addComment
function is just Javascript - I know I can do this more succinctly in JQuery, but don't want to. I've got it working with a single 'comment' just fine, but can't see how I would approach multiple.
The second part is my form validation doesn't work. My guess is that my stab into it isn't great.
var app = angular.module("ngStoryTime", []);
var _stories = [
{
Id: 1,
Title: 'Man Falls Off The World!',
Body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.',
Date: '7 March 2015',
Images: [],
Comments: [{ Body:'LOL!', Name:'Michael', Date:'1 April 2015' }, { Body:'Tis a shame that.', Name:'William', Date:'1 April 2015' }]
},
{
Id: 2,
Title: 'Woman Eats Badger!',
Body: 'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum',
Date: '8 March 2015',
Images: [],
Comments: []
}
];
app.controller('StoryController', function($scope){
$scope.pageTitle = 'Welcome to the StoryTime website!';
// Initialise the story, and blank Comment property here
this.Stories = _stories;
this.addComment = function(story){
// Is there a better way to do this??
var commentValue = document.getElementById('txtComment_' + story.Id);
var nameValue = document.getElementById('txtName_' + story.Id);
// Create the object that holds the new comment value
var myNewComment = {
Body: commentValue.value,
Name: nameValue.value,
Date: '1 May 2015'
};
// Add the comment to the array
story.Comments.push(myNewComment);
commentValue.value = '';
nameValue.value = '';
};
});
<body ng-controller='StoryController as storyCtrl'>
<h1>{{pageTitle}}</h1>
<!-- Alias the controller for use in this section -->
<div ng-repeat="story in storyCtrl.Stories">
<!-- For each Story, detail and show it -->
<h2>{{story.Title}} </h2>
<h3>{{story.Date | date:'medium' }}</h3>
<p>{{story.Body}}
<div ng-repeat="comment in story.Comments">
<h4>{{comment.Name}} - {{comment.Date | date:'medium'}} </h4>
<em>"{{comment.Body}}"</em>
</div>
<!-- Show and hide an introduction depending on if a story has a comment, or not -->
<h4 ng-show="story.Comments.length > 0">Have a Comment? There are {{story.Comments.length}} comments made so far!</h4>
<h4 ng-show="story.Comments.length == 0">Have a Comment? Be the first to comment on this excellent piece of journalism</h4>
<!-- Start of the new form that holds the story's comments, we put the story's Id on all the HtmL so we can get this later, but i'm not sure if this is actually a good idea, yet. -->
<form name="frmStory_{{story.Id}}" ng-submit="storyCtrl.addComment(story)">
Name: <br />
<input id="txtName_{{story.Id}}" required /><br />
Comment:<br/>
<textarea id="txtComment_{{story.Id}}" required></textarea>
<button ng-disabled="frmStory_{{story.Id}}.$invalid">Add My Comment</button>
</form>
<hr/>
</div>
</body>
Upvotes: 0
Views: 1537
Reputation: 136
ng-model
is a key here. Every time ng-repeat iterate through given collection it will create different scope for each piece of the repeated html code respectively to given object. Using ng-model
allows you to manage the data in given scope.
<form name="frmStory_{{story.Id}}" ng-submit="storyCtrl.addComment(story)">
Name: <br />
<input ng-model="story.newComment.Name" required /><br />
Comment:<br/>
<textarea ng-model="story.newComment.Body" required></textarea>
<button ng-disabled="frmStory_{{story.Id}}.$invalid">Add My Comment</button>
</form>
Secondly in your code :
this.addComment = function(story)
you are referencing to the instance of the controller, better way to do this is bind everything that has connection with view with $scope
$scope.addComment = function(story)
More about ng-model: https://docs.angularjs.org/api/ng/directive/ngModel
Understaning angular model and scope system is a huge milestone to understand the Angular way to build apps. I encourage you to start with that.
Upvotes: 1
Reputation: 376
Write functions in your controller this way:
$scope.yourFunctionName = function () {
}
More info here: https://docs.angularjs.org/guide/controller
As far as the form validation failing, can you paste some error messages you are getting?
Upvotes: 0