The file upload component template

The final bit of work on our component is the actual HTML template in fileupload.component.html. As this is going to be a Material dialog, we are going to use a number of Material tags here. The simplest of these tags is used to add the dialog title, which is a standard header tag with the mat-dialog-title attribute. The reason that this attribute is used is to anchor the title to the top of the dialog so that if there was any scrolling, the title would stay fixed in place:

<h2 mat-dialog-title>Choose image</h2>

With the title anchored to the top, we are ready to add our content and action buttons. First, we are going to add our content using the mat-dialog-content tag:

<mat-dialog-content>
...
</mat-dialog-content>

The first element inside our content is the message that will be displayed if the message in the code for the component is set. The test to show whether or not the message is displayed uses another Angular binding, *ngIf. Here, the Angular binding engine evaluates the expression and renders out the value if the expression is true. In this case, it's checking to see whether a message is present. It's probably not going to come as a surprise to learn that the funny-looking {{}} code is also a binding. This one is used to write out the text of the item being bound to, in this case the message:

<h3 *ngIf="message">{{message}}</h3>

The next part of the change is one of my favorite parts of the application. There is no Material version of the standard HTML file component, so if we want to display a modern-looking equivalent, we have to show the file input as a hidden component and trick it into thinking it has been activated when the user presses a Material button. The file upload input is given the fileUpload ID and triggered when the button is clicked using (click)="fileUpload.click()". When the user chooses something, the change event triggers the OnImageSelected code we wrote a couple of minutes ago:

  <button class="mat-raised-button mat-accent" md-button (click)="fileUpload.click()">Upload</button>
<input hidden #fileUpload type="file" accept="image/*" (change)="OnImageSelected(fileUpload.files)" />

Adding an image preview is as simple as adding an img tag that is bound to the preview image created when we successfully read in the image:

<div>
<img src="{{imageSource.Image}}" height="100" *ngIf="imageSource" />
</div>

Finally, we need to add in fields for reading in the tags and description. We lay these out inside the mat-form-field sections. matInput tells the template engine what styling should be put in place for text input. The most interesting part is the use of the [(ngModel)]="..." part. This applies model binding for us, telling the binding engine what field to use from our underlying TypeScript component code:

<mat-form-field>
<input type="text" matInput placeholder="Add tags" [(ngModel)]="tags" />
</mat-form-field>
<mat-form-field>
<input matInput placeholder="Description" [(ngModel)]="description" />
</mat-form-field>
If you have previously used an earlier version of Angular (prior to version 6), you have probably come across formControlName as a means of binding to values. In Angular 6+, trying to combine formControlName and ngModel no longer works. See https://next.angular.io/api/forms/FormControlName#use-with-ngmodel for more information.

There is a touch of styling that needs to be associated with mat-form-field. In the fileupload.component.scss file, we add .mat-form-field { display: block; } to style the field so that it appears on a new line. If we miss this out, the input fields appear side by side.

It's no good having a dialog that we cannot close, or that cannot return values back to the calling code. The convention that we should follow for such operations is to put our Save and Cancel buttons inside a mat-dialog-actions section. The Cancel button is marked with mat-dialog-close so that it closes the dialog for us without us having to take any actions. The Save button follows the pattern that we should be familiar with by now, and calls the Save method in our component code when the button click is detected:

<mat-dialog-actions>
<button class="mat-raised-button mat-primary" (click)="Save()">Save</button>
<button class="mat-raised-button" mat-dialog-close>Cancel</button>
</mat-dialog-actions>

We have reached the point where we need to consider where we are going to store the images when they have been selected by the user, and where they are going to be retrieved from. In the previous chapter, we used a client-side database to store our data. From now on, we are going to work with server-side code as well. Our data is going to be stored in a MongoDB database, so we now need to look at how to use Node.js and Express to connect to the MongoDB database.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.147.190