Angular Reactive Form:值不会更新组件代码,也不会在保存到数据库之前插入现有记录作为新记录

时间:2019-02-22 19:42:13

标签: angular angular-reactive-forms

我正在构建具有反应形式的angular 7应用程序,并实现了动态控件。更新记录时出现两个问题。

  1. 保存记录时不会反映我在输入字段中所做的任何更改。因此在调试时,我的表单对象不包含修改后的值,例如Name和ShortName字段。

  2. 我有一个动态添加的地址字段。假设我有两个显示在屏幕上的地址字段。如果单击“保存”按钮,则将两个记录添加为另外两个记录,而不更新现有记录。

组件代码

import { Component, Injectable, NgZone, ViewEncapsulation, ViewChild, Input } from '@angular/core';
import { OnInit } from '@angular/core';
import { FirmService } from '../services/firm.service';
import * as ClassicEditor from '@ckeditor/ckeditor5-build-classic';
import { CommonDataService } from '../services/common.data.service';
import { FormGroup, FormControl, FormBuilder, FormArray } from '@angular/forms';
import { ListItem } from '../models/listItem';



@Component({
    selector: 'mgr-firm',
    templateUrl: './firm.component.html'
})
export class FirmComponent implements OnInit {
    private Error: string;
    public FirmDetails: any;
    public EditMode: boolean;
    public Editor = ClassicEditor;
    public EditorConfig: string;
    public originalContactList: any;
    public originalCityList: any;
    public events: string[] = [];
    @Input() FirmId: number;
    DateFoundedDate: Date;
    public frmFirm: FormGroup;
    public value: Date = new Date();


    constructor(private _fb: FormBuilder, private firmService: FirmService, private commonDataService: CommonDataService) {

    }

    ngOnInit() {
        this.initializeFormModel();
        this.getFirmDetails();
    }


    initializeFormModel() {
        this.frmFirm = this._fb.group({
            firmName: [''],
            shortName: [''],
            alternateName: [''],
            dateFounded: [''],
            // intraLinks: this._fb.array([
            //     this.createCredentials()
            // ]),
            firmHistory: [''],
            People: [''],
            websites: this._fb.array([
                this.createWebsite()
            ]),
            addressess: this._fb.array([
                this.createAddress()
            ])
        });
    }


    public addWebsite(): void {
        this.websites.push(this.createWebsite());
    }

    public removeWebsite(index: number): void {
        const websites = this.frmFirm.get('websites') as FormArray;
        websites.removeAt(index);
    }

    private createWebsite(): FormGroup {
        return this._fb.group({
            websiteUrl: [''],
            username: [''],
            password: ['']
        });
    }



    public addAddress(): void {
        this.addressess.push(this.createAddress());
    }

    public removeAddress(index: number): void {
        const addressess = this.frmFirm.get('addressess') as FormArray;
        addressess.removeAt(index);
    }

    private createAddress(): FormGroup {
        return this._fb.group({
            // city: [''],
            street: [''],
            line2: [''],
            line3: [''],
            // zipCode: [''],
            phone: ['']
        });
    }




    get websites(): FormArray {
        return <FormArray>this.frmFirm.get('websites');
    }

    get addressess(): FormArray {
        return <FormArray>this.frmFirm.get('addressess');
    }



    get cities(): ListItem[] {
        return JSON.parse(this.FirmDetails.LongCitiesJson).map(x => new ListItem(x.CITY_ID, x.CITY_NAME, null));
    }


    setFormValues(FirmDetails: any) {
        this.frmFirm.patchValue({
            firmName: FirmDetails.Firm.NAME,
            shortName: FirmDetails.Firm.SHORT_NAME,
            alternateName: FirmDetails.Firm.ALTERNATE_NAME,
            dateFounded: this.getDate(FirmDetails.Firm.DATE_FOUNDED),
            firmHistory: FirmDetails.Firm.HISTORY_HTML,
            People: FirmDetails.People

        });


        const addressGroup = FirmDetails.Firm.Addresses.map(address => {
            return this._fb.group({
                street: [address.LINE1],
                line2:  [address.LINE2],
                line3:  [address.LINE3],
                phone:  [address.SWITCHBOARD_INT]
            });
        });
        const addressFormArray: FormArray = this._fb.array(addressGroup);
        this.frmFirm.setControl('addressess', addressFormArray);


        const websiteGroup = FirmDetails.Firm.Websites.map(website => {
           return this._fb.group({
                websiteUrl: [website.WEBSITE_URL],
                username:   [website.USERNAME],
                password:   [website.PASSWORD]
            });
        });
        const wesbiteFormArray: FormArray = this._fb.array(websiteGroup);
        this.frmFirm.setControl('websites', wesbiteFormArray);
    }

    getFirmDetails() {
        if (this.FirmId != null) {
            this.firmService.getFirmDetails(this.FirmId)
                .subscribe(data => {
                    this.FirmDetails = data;
                    this.originalContactList = this.FirmDetails.People;
                    this.originalCityList = JSON.parse(this.FirmDetails.LongCitiesJson);
                    this.setFormValues(this.FirmDetails);
                },
                    err => {
                        this.Error = 'An error has occurred. Please contact BSG';
                    },
                    () => {
                    });
        }
    }

    get dateFoundedDate(): string {
        if (this.FirmDetails.Firm.DATE_FOUNDED != null) {
        const dateString = this.FirmDetails.Firm.DATE_FOUNDED;
        const results = parseInt(dateString.replace(/\/Date\(([0-9]+)[^+]\//i, "$1"));
        const date = new Date(results);
        const month = date.toLocaleString('en-us', { month: 'long' });
        return (month + '-' + date.getFullYear());
        }
    }

    private getDate(dateFounded: string): Date {
        if (dateFounded != null) {
        const results = parseInt(dateFounded.replace(/\/Date\(([0-9]+)[^+]\//i, "$1"));
        const date = new Date(results);
        return new Date(date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate());
        }
    }

    saveManager() {
        this.firmService.createFirm(this.FirmDetails)
            .subscribe(data => {
                this.getFirmDetails();
                this.EditMode = !this.EditMode;
            },
                err => {
                    this.Error = 'An error has occurred. Please contact BSG';
                },
                () => {
                });
    }

    public keyContactChange(value: any): void {
        this.FirmDetails.Firm.KEY_CONTACT_ID = value;
    }

    public dateFoundedChanged(value: Date): void {
        this.FirmDetails.Firm.DATE_FOUNDED = value;
    }


    handleFilter(value) {
        if (value.length >= 1) {
            this.FirmDetails.People = this.originalContactList.filter((s) => s.FIRST_NAME.toLowerCase().indexOf(value.toLowerCase()) !== -1);
        } else {
            this.FirmDetails.People = this.originalContactList;
        }
    }

}

UI

<style>
    .desc-header {
        background-color: #FAE7D6;
        color: black
    }

    .header {
        width: 8%;
    }


    .panel-heading {
        color: white;
        background-color: #F59850;
        border-color: #ddd;
    }

    .scrollClass {
        height: 800px;
        overflow-y: scroll;
        overflow-x: hidden;


    }
</style>

<div class="card">
    <div class="card-header panel-heading">
        <span style="font-size: 18px; font-weight: bold; ">Firm Details</span>
        <div class="pull-right" style="padding-right:10px;">
            <label class="btn btn-primary" [ngClass]="{'btn-primary': EditMode, 'btn-default': !EditMode }"><input
                    type="checkbox" [(ngModel)]="EditMode" class="hidden">Edit Mode</label>

        </div>
    </div>
    <div class="card-body">

        <form [formGroup]="frmFirm" (ngSubmit)="saveManager()">
            <div *ngIf="FirmDetails && FirmDetails.Firm" class="card-body scrollClass" style="width:100%">

                <div class="form-group row">
                    <label for="inputName" class="col-md-1 col-form-label modal-label header">Name</label>
                    <div class="col-md-3">
                        <div *ngIf="!EditMode">{{FirmDetails.Firm.NAME}}</div>
                        <input *ngIf="EditMode" kendoTextBox [readonly]="false" class="form-control"
                            formControlName="firmName" />
                    </div>


                </div>

                <div class="form-group row">
                    <label for="inputTitle" class="col-md-1 col-form-label header">Short Name</label>
                    <div class="col-md-3">
                        <div *ngIf="!EditMode">{{FirmDetails.Firm.SHORT_NAME}}</div>
                        <input *ngIf="EditMode" kendoTextBox [readonly]="false" class="form-control"
                            formControlName="shortName" />
                    </div>
                </div>

                <div class="form-group row">
                    <label for="inputEmail" class="col-md-1 col-form-label header">Alternate Name</label>
                    <div class="col-md-3">
                        <div *ngIf="!EditMode">{{FirmDetails.Firm.ALTERNATE_NAME}}</div>
                        <input *ngIf="EditMode" kendoTextBox [readonly]="false" class="form-control"
                            formControlName="alternateName" />
                    </div>
                </div>

                <div class="form-group row">
                    <label for="inputEmail" class="col-md-1 col-form-label header">Date Founded</label>
                    <div class="col-md-3">
                        <div *ngIf="!EditMode">{{dateFoundedDate}}</div>
                        <kendo-datepicker *ngIf="EditMode" [format]="'MMMM yyyy'" (valueChange)="dateFoundedChanged($event)"  formControlName="dateFounded">
                        </kendo-datepicker>
                    </div>
                </div>



                <div class="form-group row">
                    <label for="inputEmail" class="col-md-1 col-form-label header">Key Contact</label>
                    <div class="col-md-3">
                        <div *ngIf="!EditMode && FirmDetails.People">{{FirmDetails.KeyContact.Name}}</div>
                        <kendo-dropdownlist *ngIf="EditMode" style="width:100%" [data]="FirmDetails.People"
                            formControlName="People" [defaultItem]="FirmDetails.KeyContact.Name" [valuePrimitive]="true" (valueChange)="keyContactChange($event)"
                            [filterable]="true" (filterChange)="handleFilter($event)" textField="Name" valueField="ID">
                        </kendo-dropdownlist>
                    </div>
                </div>

                <div class="form-group row">
                    <label for="inputEmail" class="col-md-1 col-form-label header">Websites</label>
                    <div class="col-md-9">
                        <div class="form-group row">
                            <div class="col-md-3">
                                <label for="inputEmail">Website URL</label>
                            </div>
                            <div class="col-md-3">
                                <label for="inputEmail">User Name</label>
                            </div>
                            <div class="col-md-3">
                                <label for="inputEmail">Password</label>
                            </div>
                        </div>


                        <div formArrayName="websites"
                            *ngFor="let item of frmFirm.get('websites').controls; let i = index; let last = last">
                            <div [formGroupName]="i">
                                <div class="form-group row">
                                    <div class="col-md-3">
                                        <input style="width:100%" formControlName="websiteUrl"
                                            placeholder="Website Url">
                                    </div>
                                    <div class="col-md-3">
                                        <input style="width:100%" formControlName="username" placeholder="User Name">
                                    </div>
                                    <div class="col-md-3">
                                        <input style="width:100%" formControlName="password" placeholder="Password">
                                    </div>
                                    <div *ngIf="EditMode" class="col-md-3">
                                        <button (click)="removeWebsite()">Remove Website</button>
                                    </div>
                                </div>


                            </div>

                        </div>
                        <div *ngIf="EditMode">
                            <button (click)="addWebsite()">Add Website</button>
                        </div>
                    </div>
                </div>


                <div class="form-group row">
                    <div class="col-md-12">


                        <div formArrayName="addressess"
                            *ngFor="let item of frmFirm.get('addressess').controls; let i = index;">

                            <div [formGroupName]="i">

                                <div class="form-group row">
                                    <label class="col-md-1 col-form-label header" attr.for="{{'streetId' + i}}">Street
                                        1</label>
                                    <div class="col-md-9">
                                        <input class="form-control" id="{{'streetId' + i}}" type="text"
                                            placeholder="Street address (required)" formControlName="street">

                                    </div>
                                </div>

                                <div class="form-group row">
                                    <label class="col-md-1 col-form-label header" attr.for="{{'line2Id' + i}}">Line
                                        2</label>
                                    <div class="col-md-9">
                                        <input class="form-control" id="{{'line2Id' + i}}" type="text"
                                            placeholder="Street address (second line)" formControlName="line2">
                                    </div>
                                </div>

                                <div class="form-group row">
                                    <label class="col-md-1 col-form-label header" attr.for="{{'line3Id' + i}}">Line
                                        3</label>
                                    <div class="col-md-9">
                                        <input class="form-control" id="{{'line3Id' + i}}" type="text"
                                            placeholder="Street address (third line)" formControlName="line3">
                                    </div>
                                </div>



                                <div class="form-group row">
                                    <label class="col-md-1 col-form-label header" attr.for="{{'phoneId' + i}}">Phone
                                        </label>
                                    <div class="col-md-9">
                                        <input class="form-control" id="{{'phoneId' + i}}" type="text"
                                            placeholder="Phone" formControlName="phone">
                                    </div>
                                </div>

                            </div>
                        </div>
                        <div *ngIf="EditMode">
                            <button (click)="addAddress()">Add Address</button>
                        </div>
                    </div>
                </div>


                <div class="form-group row">
                    <div class="col-md-12" style="padding-top:10px;padding-left: 0px;padding-right: 30px;">
                        <div class="desc-header">Firm History</div>
                        <div class="divEditor">
                            <ckeditor [editor]="Editor" [id]="'ckFirmHistory'" *ngIf="EditMode"
                                formControlName="firmHistory" style="font-size: 11px;" debounce="500"
                                [config]="EditorConfig">
                            </ckeditor>
                            <div style="padding: 10px" *ngIf="!EditMode" [innerHTML]="FirmDetails.Firm.HISTORY_HTML">
                            </div>
                        </div>
                    </div>
                </div>



            </div>
            <div class="btn-toolbar" style="padding-top:40px;">
                <span> <button class="btn btn-default btn mr-3">
                        <i class="fa fa-file-pdf-o"></i>
                        Download Template
                    </button>
                </span>
                <span> <button class="btn btn-default btn mr-3">
                        <i class="fa fa-th-large"></i>
                        Upload Template Data
                    </button>
                </span>
                <span *ngIf="EditMode"><button type="submit" class="btn btn-primary btn-view-all btn mr-3">Save</button>

                </span>
                <span><button type="button" class="btn btn-primary btn-view-all btn mr-3"
                        (click)="cancelManager">Cancel</button>
                </span>
                <span><button type="button" style="float: right;" class="btn btn-primary btn-view-all"
                        (click)="deleteManager()">Delete</button>
                </span>
            </div>
        </form>
    </div>
</div>

服务器端控制器代码

[HttpPut]
        [SkipTokenAuthorization]
        public void CreateFirm(FirmViewModel model)
        {

            var firmService = GetService<FIRM>();

            var firm = firmService.GetWithIncludes(model.Firm.ID);

            if (firm != null)
            {
                firm.NAME = model.Firm.NAME;
                firm.SHORT_NAME = model.Firm.SHORT_NAME;
                firm.KEY_CONTACT_ID = model.Firm.KEY_CONTACT_ID;
                firm.ALTERNATE_NAME = model.Firm.ALTERNATE_NAME;
                firm.DATE_FOUNDED = model.Firm.DATE_FOUNDED;
                firm.HISTORY_HTML = model.Firm.HISTORY_HTML;
                firm.Addresses = model.Firm.Addresses;
                firm.Websites=  model.Websites;
                firmService.Update(firm);
            }
            else
            {
                //var m = new MANAGER(){PERSON = new PERSON()};
                //m.PERSON.EMAIL_ADDRESS1 = model.Person.EMAIL_ADDRESS1;

            }

1 个答案:

答案 0 :(得分:0)

1)您的saveManager似乎没有从frmFirm中读取值,而是提交了数据对象FirmDetails -您需要更新模型(或更佳的模型)尚未提交您的模型副本)以及表单值,然后再将其提交到服务器。

2)您的服务器端“ firmService.Update”是否尊重模型中的现有地址?您是否正确传递ID以确保不重新添加现有地址?这似乎是造成重复的原因