Build a Simple Progress Bar Component in Ionic 3

Understand Input and Output in Custom Components

A component needs a way for data to flow in and flow out. Data can flow into the component (from its parent component) through its @Input, and data can flow out of the component (up to its parent component) through its @Output. We can use property binding to provide a component with input, and we can make the component fire an event to create output.

Setting up @Input and @Output in a component might look like this:

import { Component, Input, Output, EventEmitter } from '@angular/core';
 
@Component({
  selector: 'my-component',
  templateUrl: 'my-component.html'
})
export class MyComponent {
 
    @Input('propertyName') myValue;
    @Output() eventName = new EventEmitter();
 
    constructor(){ }
 
}

If we want to pass in some data to this component now, we can use the propertyName input to do that, like this:

<my-component [propertyName]="someValue"></my-component>

Once we do that, whatever someValue is will be available anywhere inside of our custom component as this.myValue since we set that up using @Input. If we want to trigger an event from within the component then we can just emit some data using the EventEmitter we set up using @Output like this:

this.eventName.emit({data: someData});

which would then allow us to listen for that even like this:

<my-component [propertyName]="someValue" (eventName)="doSomething()"></my-component>

For the progress bar component, we will just be using @Input as we have no need to send any data back to the parent component. We just want to be able to supply our progress bar component with a value that it should use to display a certain percentage of progress.

Generate the progress bar component
ionic g component ProgressBar

This will generate the component for us, but we are also going to have to import and declare it in our app.module.ts file.

import { ProgressBarComponent } from '../components/progress-bar/progress-bar';

@NgModule({
  declarations: [
    ...
    ProgressBarComponent
  ]
})
export class AppModule {}

Note that you only need to include the custom component in the declarations array, you don’t need to add it to the entryComponents as well.

Modify progress-bar.ts
import { Component, Input } from '@angular/core';

@Component({
  selector: 'progress-bar',
  templateUrl: 'progress-bar.html'
})
export class ProgressBarComponent {
  @Input('progress') progress;

  constructor() { }

}

All we are doing here is setting up an @Input called progress that we will use to control how full the progress bar should be. This is actually all we need to do for this file, the rest of the logic will be handled in the template.

Modify progress-bar.html
<div class="progress-outer">
  <div class="progress-inner" [style.width]="progress + '%'">
    {{progress}}%
  </div>
</div>

We create a container <div> so that we can apply the appropriate styling to this component later. The interesting part is the inner <div>, we use property binding to bind our progress input to the width property for the element (along with a percentage symbol). So if we give this component an input of 50, it will set the width of that inner <div> to 50%. Then we just render out that value as text inside of the <div>.

That will control how full the progress bar should be, and all we have left to do is add a bit of styling.

Modify progress-bar.scss
progress-bar {
  .progress-outer {
    width: 100%;
    margin: 10px 2%;
    padding: 3px;
    text-align: center;
    background-color: #f4f4f4;
    border: 1px solid #dcdcdc;
    color: #fff;
    border-radius: 20px;
  }
  .progress-inner {
    min-width: 15%;
    white-space: nowrap;
    overflow: hidden;
    padding: 5px;
    border-radius: 20px;
    background-color: map-get($colors, primary);
  }
}

All this really does is style the component so that it looks like a loading bar.

Use the Component

Now you can just use the following syntax in any of your templates:

<progress-bar [progress]="loadProgress"></progress-bar>

This example would bind the progress property to a member variable called loadProgress that would be set up in the TypeScript file. You can even change this loadProgress variable dynamically (as a download is progressing, for example) to create an animated effect like this:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,458评论 0 10
  • 内连接:inner join, natural join 就是典型的内连接。内连接不保留未匹配元组的连接。 例如:...
    Akushu阅读 329评论 0 0
  • Im getting old and lazy, don't have much passion to write...
    游离_阅读 423评论 0 0
  • 作业: 昨天下班回到家,儿子和小姨、妹妹、我的同学在客厅看电视。因计划饭后要外出我提醒儿子还有作业没完成哟,他赖皮...
    琴韵华影阅读 163评论 0 5
  • 当你发现那个被尊重的自己,被而对方起你眼里的陌生人,这或许也是他们给你的呢,那是不是可以说是,过去的你之所以从没受...
    叶静生阅读 270评论 0 0