Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

snackboy
snackboy

Posted on

Iterative Development && Abstraction - Part 2

Inpart 1, I wrote about taking blocks of static note cards and abstracting them into a carousel using a@for loop. These cards were utilized on alearn more page. The content for the cards were moved from the html template to the an JSON array in the controller (.ts) file.

Now that this is developed and working, another iteration of abstraction can be performed to see how the carousel could be made more useful. The idea here will be to move the carousel code out of thelearn more template and move it into its own component.

Angular makes creating and implementing components super easy, barely an inconvenience [#RyanGeorge].

(Note that code snippets are at a high to mid level and are only provided to convey the idea of the development pattern.)

PS D:\thecookery> ng generate component ui/carouselCREATE src/app/ui/carousel/carousel.component.html (24 bytes)CREATE src/app/ui/carousel/carousel.component.spec.ts (633 bytes)CREATE src/app/ui/carousel/carousel.component.ts (255 bytes)CREATE src/app/ui/carousel/carousel.component.scss (0 bytes)
Enter fullscreen modeExit fullscreen mode

Now that the component is created, the code from thelearn more template can be moved into carousel component. The first thing to do is replace autogeneratedcarousel template content

<p>carousel works!</p>
Enter fullscreen modeExit fullscreen mode

with thelearn more content

@for( card of cards; track card.index) {    @if( slide == card.index) {        <div>            <div>                <div>                    {{card.title}}                </div>                <div>{{card.text}}</div>            </div>        </div>        <div>            <button (click)="prevSlide()"><span ></span></button>            <button (click)="nextSlide()"><span ></span></button>        </div>    }}
Enter fullscreen modeExit fullscreen mode

Next, the carousel controller need to know about the slide controls. This is accomplished by moving from the learn more controller thenextSlide() andprevSlide() functions to the carousel and defining the necessary variables.

(Note that I am doing this a bit old school Angular and not using the newer standalone component. Old school means that then the component must be registered in theapp modules area.)

import { Component } from '@angular/core';@Component({  selector: 'app-carousel',  templateUrl: './carousel.component.html',  styleUrl: './carousel.component.scss'})export class CarouselComponent {    public slide: number = 1;    public slideCount = 5;    nextSlide() {        this.slide = this.slide + 1;        if (this.slide > this.slideCount) {            this.slide = 1;        }    }    prevSlide() {        this.slide = this.slide - 1;        if (this.slide < 1) {            this.slide = this.slideCount;        }    }}
Enter fullscreen modeExit fullscreen mode

Looking at the code above, there is still a bit more work to do. The first thing is that the new carousel has no idea what the cards are as they are contained in thelearn more controller. Another issue to address is the slide count as we know not all carousels would have 5 slides.

Addressing the first issue, the cards need to be passed into the carousel component. To do this, acards input and card object need to be created in the carousel. Address the second issue, theslideCount value can be removed and replaced with the length of the cards array.

import { Component, Input } from '@angular/core';export class Card {    title: string = '';    text: string = '';    index: number = 0;  }@Component({  selector: 'app-carousel',  templateUrl: './carousel.component.html',  styleUrl: './carousel.component.scss'})export class CarouselComponent {    @Input() cards: Array<Card> = [];    public slide: number = 1;    nextSlide() {        this.slide = this.slide + 1;        if (this.slide > this.cards.length) {            this.slide = 1;        }    }    prevSlide() {        this.slide = this.slide - 1;        if (this.slide < 1) {            this.slide = this.cards.length;        }    }}
Enter fullscreen modeExit fullscreen mode

Next, any CSS specific to the carousel needs to be added its CSS file.

The last step is to replace the existing learn more carousel code with new carousel component. The learn more template goes from this:

<style>.card {    background-image:        linear-gradient(180deg, white 3rem, #F0A4A4 calc(3rem), #F0A4A4 calc(3rem + 2px), transparent 1px),        repeating-linear-gradient(0deg, transparent, transparent 1.5rem, #DDD 1px, #DDD calc(1.5rem + 1px));    box-shadow: 1px 1px 3px rgba(0,0,0,.25);    background-color: white;}.card-title {    font-size: 1.5em;}/*https://codepen.io/teddyzetterlund/pen/YPjEzP*/</style><div>    <img width=100 src="/assets/logo.png">    <div>learn more</div>    <button [routerLink]="['/register']">Become a member...</button>          </div>@for( card of cards; track card.index) {    @if( slide == card.index) {        <div>            <div>                <div>                    {{card.title}}                </div>                <div>{{card.text}}</div>            </div>        </div>        <div>            <button (click)="prevSlide()"><span ></span></button>            <button (click)="nextSlide()"><span ></span></button>        </div>    }}
Enter fullscreen modeExit fullscreen mode

...to this:

<div>    <img width=100 src="/assets/logo.png">    <div>learn more</div>    <button [routerLink]="['/register']">Become a member...</button>          </div><app-carousel [cards]="cards"></app-carousel>
Enter fullscreen modeExit fullscreen mode

Thelearn more controller can be reduced to:

import { Component } from '@angular/core';@Component({  selector: 'app-learn-more',  templateUrl: './learn-more.component.html',  styleUrls: ['./learn-more.component.scss']})export class LearnMoreComponent {    public cards: Array<any> = [        {   title:  'create and edit recipes',            text:   `   At mealHash, you can create and edit recipes. This includes areas for ingredients, instructions, and other key points                         you would expect as part of recipe.                     `,            index: 1        },        {   title:  'stores',            text:   `   You can also add stores into your mealHash, create grocery lists and easily add and remove items from the list.                         Ingredients can be added to directly to your grocery  lists from your recipes allowing you manage your shopping experience.                    `,            index: 2        },        {   title:  'search',            text:   `   Use the search page to find recipes by name or that have a particular ingredient. When you find a recipe you want to try, to can copy                        it right to your recipe binder and then edit it to make it your own.                      `,            index: 3        },        {   title:  'recipe feed',            text:   `   A feed is available of your and others recipes as they are added to mealhash. Just like the search, you can add a recipe to your                         mealhash and modify it to make it your own.                    `,            index: 4        },        {   title: 'cost',            text:  `    mealhash is free and we intend to keep it that way. But will gladly accept donations to keep the site running. In future,                         we may build out premium features as we have more mealhasher feedback. But our goal is to make mealhash a must have site                        for your recipes, grocery lists, and meal plans.                    `,            index: 5        }    ]}
Enter fullscreen modeExit fullscreen mode

...which is effectively the content of the cards.

By doing iterative development with abstraction along the way, we ended up with a carousel component that can be used elsewhere in the project. And just by modifying the one component - for example adding images to the card with animage key/value pair - the capability will persist to where ever that component is implemented.

Going through process of iterative development and abstraction helps you get to lower code solutions thus making your code more manageable, efficient and pliable.

There is one more abstraction I will share regarding this particular component - stay tuned for part 3. If you can think of other abstractions, please feel free to share in the comments.

Cheers!

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

seasoned web developer working on mealhash.com
  • Location
    south central pennsylvania
  • Education
    Some college but mostly self-educated
  • Work
    senior application developer in higher ed
  • Joined

More fromsnackboy

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp