Page 62 - MSDN Magazine, July 2017
P. 62

The Working Programmer TED NEWARD How To Be MEAN: Angular Ins and Outs
Welcome back, MEANers.
Last month I talked briefly about how to create components
that can synthesize data (such as the current year) and display it as part of the component’s view. I also briefly experimented with the Angular Command-Line Interface (CLI) tool, “ng,” and used that to generate a new application. In this month’s column, I’ll go further down the Web component path and talk about how to pass information into—and out of—a given Angular component.
In this particular case, as part of my ongoing loose example around tracking speakers and their talks, I’m going to build a small component to track the “upvotes” from users/attendees so that people can rate speakers’ talks and offer feedback. I’ll call this component the UpvoteComponent; you want the component to obey the following (highly simplified) set of specs:
• The Upvote should initialize the “Upvote” property from the “votes” attribute. Default to 0 if no votes attribute is provided.
• The Upvote should let text between the tags act as the label.
• The Upvote should display an up-arrow character and when the user clicks on the up-arrow, it should increment
the vote count.
• The Upvote should, when clicked, also notify interested parties
(such as other Angular components) of the new vote count.
If the UpvoteComponent is actually going to use a full MVC approach, then you also need a “model” class, which we’ll call Upvote.
In addition, you’re going to deliberately structure this Upvote- Component to use a simplified, miniaturized Model-View- Controller (MVC) approach because this will help structure the application as a whole later.
UpvoteComponent
The first step in any component is to generate the basic scaffolding of the component and the Angular CLI gives you that with a single
Figure 1 Verifying the Upvote Class
import {Upvote} from './upvote';
describe('Upvote', () => {
it('should create an instance', () => {
expect(new Upvote(0)).toBeTruthy(); });
it('should remember the votes passed in via the constructor', () => { let v = new Upvote(12);
expect(v.count).toEqual(12);
});
it('should increment the vote count by one when incremented', () => { let v = new Upvote(12);
v.increment();
expect(v.count).toBe(13);
}); });
56 msdn magazine
command-line command: “ng generate component upvote.” This will create a series of four files (the same four-part .ts/.cs”/.html/.spec.ts split you got before) in an upvote subdirectory.
Upvote
If the UpvoteComponent is actually going to use a full MVC approach, then you also need a “model” class, which we’ll call Upvote. This can be scaffolded out using the Angular CLI, as well, by running “ng generate class upvote --spec true.” (The parameter at the end asks the CLI to generate a unit-test file for the Upvote class, and we all like to write unit tests, right?) This will create src/app/upvote.ts and src/app/upvote.spec.ts files. The first will be effectively an empty class, waiting for a more intelligent/feature- driven class definition, which you’ll promptly provide:
export class Upvote { constructor(private votes : number) { }
public get count() { return this.votes; }
public increment() { this.votes++; } }
(Note: We could call this a “Vote” model, because that’s what it’s really tracking, but it’s common in Angular components for the model to directly reflect the component itself, so if we’re calling this an “UpvoteComponent,” consistency suggests we call it an “Upvote.”Thisis,ofcourse,entirelyaesthetic,andteamscan—and should—come up with their own naming conventions that make sense to them, at least until the Angular community as a whole has locked some in stone.)
And again, because you’re a good, unit-test-loving developer, you’ll also set up a quick set of unit tests in the upvote.spec.ts file































































   60   61   62   63   64