To resolve the reference file issue, auto import extension helps us a lot really. And on the opposite side our application is working fine.
So here, tomorrow if we decide to change the name of this event from change to something else our application will certainly break or might not work properly. Let’s take an experiment.
- export class StarComponent implements OnInit {
-
- @Input('isFavorite') isSelected: boolean;
- @Output() click = new EventEmitter();
-
- constructor() { }
-
- ngOnInit() {
- }
-
- onClick(){
- this.isSelected = !this.isSelected;
- this.click.emit({ newValue: this.isSelected });
- }
- }
Now look, the subscriber of Star component is still expecting a change event.
- <star [isFavorite]="post.isFavorite" (change)="onStarChange($event)"></star>
And if you run the application, our component is working properly but doesn’t show the log messages in the console which we’re displaying through onStarChange() event of Star component.
Now you might be thinking that app.component.html contains change event which doesn’t exist then why isn't our application broken. It is because our app component is expecting that it may exist sometimes in the future that’s why it doesn’t give us any error in the browser. But the code actually is broken because event handler onStarChange() is not called. So always it is the better choice to use alias to make sure if in the future we rename this field, the subscriber of the component is not going to break. So,
- export class StarComponent implements OnInit {
-
- @Input('isFavorite') isSelected: boolean;
- @Output('change') click = new EventEmitter();
-
- constructor() { }
-
- ngOnInit() {
- }
-
- onClick(){
- this.isSelected = !this.isSelected;
- this.click.emit({ newValue: this.isSelected });
- }
- }
And now if we run the application, we’ll see it is working fine. And our onStarChange() method is logging the message in console.
Templates
We’ve seen 2 forms of using template. One way is to use the template externally and then we use the templateUrl property of component metadata to specify the path to the template file and another approach is to use template property. So we can add the template inline here. Now please don’t mix these approaches, you can follow only 1 approach.
- @Component({
- selector: 'star',
- templateUrl: './star.component.html',
- template: '',
- styleUrls: ['./star.component.css']
- })
Now you might ask which approach is better.
It really depends, if you’re building a small component with a very simple template we can add the template here in the component declarator which would be easy to work with and to import it into multiple applications. Yes you can use your component into multiple applications. Just copy your component folder and paste it into any application where you want and just use it like we do here in app component. If your template is more than 5 lines of code, you can think your own that this code is quite busy and too noisy. So in that case the best approach is to store it in the external file.
Now you might think that as it is a separate file so there will be a new request for template files. Actually that’s not the case here. Remove the redundant template.
- @Component({
- selector: 'star',
- templateUrl: './star.component.html',
- styleUrls: ['./star.component.css']
- })
Open your app.component.html and place a heading here with any name.
- <h2>Usama Shahid</h2>
- <star [isFavorite]="post.isFavorite" (change)="onStarChange($event)"></star>
Now back in the browser, in Chrome developer tools under the Network tab there are multiple requests to the server. And if you see in the list there is no request of any of our template files.
Our template files are actually bundled along with our source code. So here we have main.js, so all our typescript code is transpiled into javascript and placed inside this bundle. Now click on main.js and go to the response tab and here you’ll see the content of main bundle
Look all of our external templates are actually bundled along with our javascript code. So there is no separate request to the server to download the template files.
Styles
As we build components, sometimes we need to apply styles on the components. In Angular there are 3 ways to apply styles to a component but first of all let’s remove the unnecessary code.
- export class StarComponent {
-
- @Input('isFavorite') isSelected: boolean;
- @Output('change') click = new EventEmitter();
-
- onClick(){
- this.isSelected = !this.isSelected;
- this.click.emit({ newValue: this.isSelected });
- }
- }
Th other way is by using styles property. It is similar to stylesUrls. We put the array here as well. And here we use backticks to use the multiple lines for styling purposes. And with this approach we can use inline styles in this component and this is exactly writing template inline. So if you’re working with small components with only a few styles, you may choose to write your styles here rather than in an extra noise stylesheet.