Angular 4 - Реализация многостраничной формы с динамическими полями формы - PullRequest
0 голосов
/ 23 сентября 2018

Я пытался реализовать многостраничную форму в Angular 4, которая должна быть в состоянии сделать следующее:

1- Разрешить пользователю перемещаться по различным страницам формы.

2-Должен иметь возможность вернуться на предыдущую страницу формы и по-прежнему иметь возможность видеть сделанные им записи.

3- Уметь динамически добавлять поля формы, такие как более одного номера телефона, адреса и т. Д..

Мне удалось достичь первых двух функций в моей форме, следуя инструкциям, описанным по ссылке ниже:

https://www.cc28tech.com/angular-multi-step-wizard-part-1/

Однако третья часть - этохитрый для меня.Я не в состоянии понять, как идти вперед, достигая того же самого.Я понимаю, что мне придется использовать массив форм для того же самого, но реализовать то же самое в коде, упомянутом в ссылке выше, сложно для меня.Если кто-нибудь может подсказать мне, как этого добиться, это было бы мне очень полезно.

Ниже приведен фрагмент кода для того же самого:

formData.model.ts

export class FormData {
firstName: string = '';
lastName : string = '';
email: string = '';
work: string = '';
street: string = '';
city: string = '';
state: string = '';
zip: string = '';

clear() {
    this.firstName = '';
    this.lastName = '';
    this.email = '';
    this.work = '';
    this.street = '';
    this.city = '';
    this.state = '';
    this.zip = '';
   }
 }

 export class Personal {
firstName: string = '';
lastName : string = '';
email: string = '';
}

export class Address {
street: string = '';
city: string = '';
state: string = '';
zip: string = '';
}

formData.service.ts

import { Injectable } from '@angular/core';
import { FormData, Personal, Address } from './formData.model';
import { WorkflowService }  from '../workflow/workflow.service';
import { STEPS } from '../workflow/workflow.model';

@Injectable()
  export class FormDataService {

   private formData: FormData = new FormData();
   private isPersonalFormValid: boolean = false;
   private isWorkFormValid: boolean = false;
   private isAddressFormValid: boolean = false; 

constructor(private workflowService: WorkflowService) { }

       getPersonal(): Personal {
    // Return the Personal data
       var personal: Personal = {
        firstName: this.formData.firstName,
        lastName: this.formData.lastName,
        email: this.formData.email
    };
    return personal;
  }

   setPersonal(data: Personal) {
    // Update the Personal data only when the Personal Form had been 
   validated successfully
    this.isPersonalFormValid = true;
    this.formData.firstName = data.firstName;
    this.formData.lastName = data.lastName;
    this.formData.email = data.email;
    // Validate Personal Step in Workflow
    this.workflowService.validateStep(STEPS.personal);
 }

   getWork() : string {
    // Return the work type
    return this.formData.work;
 }

  setWork(data: string) {
    // Update the work type only when the Work Form had been validated 
    successfully
    this.isWorkFormValid = true;
    this.formData.work = data;
    // Validate Work Step in Workflow
    this.workflowService.validateStep(STEPS.work);
}

    getAddress() : Address {
    // Return the Address data
        var address: Address = {
        street: this.formData.street,
        city: this.formData.city,
        state: this.formData.state,
        zip: this.formData.zip
    };
    return address;
}

  setAddress(data: Address) {
    // Update the Address data only when the Address Form had been validated 
    successfully
    this.isAddressFormValid = true;
    this.formData.street = data.street;
    this.formData.city = data.city;
    this.formData.state = data.state;
    this.formData.zip = data.zip;
    // Validate Address Step in Workflow
    this.workflowService.validateStep(STEPS.address);
}

getFormData(): FormData {
    // Return the entire Form Data
    return this.formData;
}

resetFormData(): FormData {
    // Reset the workflow
    this.workflowService.resetSteps();
    // Return the form data after all this.* members had been reset
    this.formData.clear();
    this.isPersonalFormValid = this.isWorkFormValid = 
    this.isAddressFormValid = false;
    return this.formData;
}

isFormValid() {
    // Return true if all forms had been validated successfully; otherwise, 
        return false
        return this.isPersonalFormValid &&
            this.isWorkFormValid && 
            this.isAddressFormValid;
    }
 }

рабочий процесс.model.ts

export const STEPS = {
personal: 'personal',
work: 'work',
address: 'address',
result: 'result'
  }

workflow-guard.service.ts

import { Injectable } from '@angular/core';
import {
CanActivate, Router,
ActivatedRouteSnapshot,
RouterStateSnapshot,
CanLoad, Route
} from '@angular/router';

  import { WorkflowService } from './workflow.service';

  @Injectable()
  export class WorkflowGuard implements CanActivate {
  constructor(private router: Router, private workflowService: 
  WorkflowService { }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): 
  boolean {
    let path: string = route.routeConfig.path;

    return this.verifyWorkFlow(path);
}

verifyWorkFlow(path) : boolean {
    console.log("Entered '" + path + "' path.");

    // If any of the previous steps is invalid, go back to the first invalid 
      step
    let firstPath = this.workflowService.getFirstInvalidStep(path);
    if (firstPath.length > 0) {
        console.log("Redirected to '" + firstPath + "' path which it is the 
    first invalid step.");
        let url = `/${firstPath}`;
        this.router.navigate([url]);
        return false;
    };

    return true;
 }
}

workflow.service.ts

import { Injectable } from '@angular/core';

import { STEPS }   from './workflow.model';

@Injectable()
export class WorkflowService {
private workflow = [
    { step: STEPS.personal, valid: false },
    { step: STEPS.work, valid: false },
    { step: STEPS.address, valid: false },
    { step: STEPS.result, valid: false }
];

validateStep(step: string) {
    // If the state is found, set the valid field to true 
    var found = false;
    for (var i = 0; i < this.workflow.length && !found; i++) {
        if (this.workflow[i].step === step) {
            found = this.workflow[i].valid = true;
        }
    }
}

resetSteps() {
    // Reset all the steps in the Workflow to be invalid
    this.workflow.forEach(element => {
        element.valid = false;
    });
}

getFirstInvalidStep(step: string) : string {
    // If all the previous steps are validated, return blank
    // Otherwise, return the first invalid step
    var found = false;
    var valid = true;
    var redirectToStep = '';
    for (var i = 0; i < this.workflow.length && !found && valid; i++) {
        let item = this.workflow[i];
        if (item.step === step) {
            found = true;
            redirectToStep = '';
        }
        else {
            valid = item.valid;
            redirectToStep = item.step
        }
    }
    return redirectToStep;
  }
}

personal.component.ts

 import { Component, OnInit } from '@angular/core';
 import { Router }  from '@angular/router';
 import { Personal }   from '../data/formData.model';
 import { FormDataService } from '../data/formData.service';

 @Component({
selector: 'app-personal',
templateUrl: './personal.component.html'

})
export class PersonalComponent implements OnInit {
title = 'Tell us about Yourself';
personal: Personal;
form: any;

constructor(private router: Router, private formDataService: 
FormDataService) {}

 ngOnInit() {
  this.personal = this.formDataService.getPersonal();
  console.log('Personal feature loaded!');
   } 

save(form: any): boolean {
  if (!form.valid) {
      return false;
  }

  this.formDataService.setPersonal(this.personal);
  return true;
}

 goToNext(form: any) {
  if (this.save(form)) {
      // Navigate to the work page
      this.router.navigate(['vendorOnboarding/work']);
  }
}
 back()
 {

  this.router.navigate(['/login']);
  } 
}

personal.component.html

<form #personalForm="ngForm" class="editForm" novalidate>
<div class="tab-pane fade in active">
    <h4 class="head text-center">{{title}}</h4>
    <br/>
    <div class='row'>
        <div class='col-xs-offset-1 col-xs-10 col-sm-offset-2 col-sm-8'>
            <div class="row">
                <div class='col-xs-12 col-sm-6'>
                    <div class="form-group">
                        <label class="control-label" for="firstname">First 
                        Name</label>  
                        <input class="form-control input-md" 
                        #firstname="ngModel" required id="firstname" 
                       name="firstname" type="text" placeholder="First Name" 
                       [(ngModel)]="personal.firstName">

                        <div class="alert alert-danger" 
                        [hidden]="firstname.valid">First Name is 
                         required</div>
                    </div>
                </div>
                <div class='col-xs-12 col-sm-6'>
                    <div class="form-group">
                        <label class="control-label" for="lastname">Last 
                         Name</label>  
                        <input class="form-control input-md" 
                         #lastname="ngModel" required id="lastname" 
                         name="lastname" type="text" placeholder="Last Name" 
                         [(ngModel)]="personal.lastName">
                        <div class="alert alert-danger" 
                        [hidden]="lastname.valid">Last Name is 
                         required</div>
                    </div>
                </div>
            </div>
            <div class="form-group">
                <label class="control-label" for="email">Email</label>
                <input class="form-control input-md" #email="ngModel" 
                required pattern="^[^\s@]+@[^\s@]+\.[^\s@]{2,}$" id="email" 
                name="email" type="text" placeholder="Email" 
                [(ngModel)]="personal.email">

                <div class="alert alert-danger" [hidden]="email.valid">Email 
                 is required and must be valid</div>
            </div>

            <div class="form-group text-center">
                <button class="btn btn-success btn-outline-rounded btn-info" 
                [disabled]="!personalForm.valid" 
                (click)="goToNext(personalForm)"> Next <span style="margin- 
                left:10px;" class="glyphicon glyphicon-arrow-right"></span> 
           </button>
            </div>
        </div>
       </div>
    </div>
</form>

Мое единственное требование - разрешить пользователю динамически добавлять поля формы, например, несколько адресов электронной почты.что я ищу, так это наличие кнопки + и - в моей форме, которая позволяет пользователю добавлять несколько адресов электронной почты.Мне удалось найти несколько решений для одного и того же, но я не смог воспроизвести одно и то же в приведенном выше коде.

Пожалуйста, объясните мне, как этого добиться.

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...