Angular对象绑定

huangapple go评论64阅读模式
英文:

Angular Object Binding

问题

I don't have too much experience with angular but there is a task that I have to handle in my job. Basically, I have a form where users can insert values and these values directly go to the backend for processing.
On the form we are submitting a PolicyDocument which has these parameters:

import {ContactFrequency} from './ContactFrequency';


export class PolicyDocument {
    id: number;
    name: string;
    description: string;
    file: string;
    validFrom: string;
    country: string;
    majorVersion: number;
    minorVersion: number;
    status: string;// TODO dmann make enum or string set
    primaryText: string;
    secondaryText: string;
    textBlocks: TextBlock[];
    contactFrequency?: ContactFrequency;

    constructor() {
    }
}

And the ContactFrequency is like this:

export class ContactFrequency{
    id:number;
    contactFrequency: number;

    constructor() {
    }
}

And the form that we are taking values:

<label for="inputContactFrequency" class="col-1 col-form-label">Contact Frequency (Days)</label>
<div class="col-2 pr-0">
<input type="number" class="form-control" id="inputContactFrequency" placeholder="(Optional)"
[ngModel]="detail?.contactFrequency?.contactFrequency"
name="contactFrequency.contactFrequency" [disabled]="fieldsDisabled()" min="0"/>
</div>

Sorry for the messy naming convention. My problem is; whenever i insert a value, the payload that goes to back-end is like below.

contactFrequency: 180

If i dont insert a value it is:

contactFrequency:{
   contactFrequency: null
}

The payload that goes when I am not inserting a value is ok, it works as I expect but whenever I insert a value it doesn't go as an object. Is there a quick/easy way to modify it as passes object to backend?

When the form filled and submitted, first handleCreate method being activated:

handleCreate(policyDocument: PolicyDocument) {
    this.userFeedbackService.clearAllUserFeedback();
    if this.validatePolicyDocumentDate(policyDocument)) {
        this.policyDocumentService.create(policyDocument).subscribe(
            (response) => {
                console.log('handleCreate returned ', response);
                this.router.navigate(['/policies'])
                    .then(() => this.userFeedbackService.clearAndAddSuccess('Policy created successfully'));
            },
            () => {
                this.removeDefaultValidityInDays();
                window.scrollTo({top: 0, behavior: 'smooth'});
            });
    } else {
        window.scrollTo({top: 0, behavior: 'smooth'});
    }
}

And then it goes to service:

create(policyDocument: PolicyDocument): Observable<PolicyDocument> {
    console.log("Policy Document for frequency rule: " + policyDocument);
    consolesole.log("Contact Frequency for frequency rule: " + policyDocument.contactFrequency?.contactFrequency);
    return this.http
        .put(POLICY_DOCUMENTS_API, policyDocument)
        .map(data => {
            this.userFeedbackService.clearAndAddSuccess('Policy document has been created successfully');
            return <PolicyDocument>data;
        })
        .catch((err) => {
            this.userFeedbackService.addError('Failed creating policyDocument');
            throw new Error(err.toString());
        });
}
英文:

I don't have too much experience with angular but there is a task that I have to handle in my job. Basically, I have a form where users can insert values and these values directly go to the backend for processing.
On the form we are submitting a PolicyDocument which has these parameters:

import {ContactFrequency} from './ContactFrequency';


export class PolicyDocument {
    id: number;
    name: string;
    description: string;
    file: string;
    validFrom: string;
    country: string;
    majorVersion: number;
    minorVersion: number;
    status: string;// TODO dmann make enum or string set
    primaryText: string;
    secondaryText: string;
    textBlocks: TextBlock[];
    contactFrequency?: ContactFrequency;

    constructor() {
    }
}

And the ContactFrequency is like this:

export class ContactFrequency{
    id:number;
    contactFrequency: number;

    constructor() {
    }
}

And the form that we are taking values:

            <label for="inputContactFrequency" class="col-1 col-form-label">Contact Frequency (Days)</label>
            <div class="col-2 pr-0">
                <input type="number" class="form-control" id="inputContactFrequency" placeholder="(Optional)"
                       [ngModel]="detail?.contactFrequency?.contactFrequency"
                       name="contactFrequency.contactFrequency" [disabled]="fieldsDisabled()" min="0"/>
            </div>

Sorry for the messy naming convention. My problem is; whenever i insert a value, the payload that goes to back-end is like below.

contactFrequency: 180

If i dont insert a value it is:

contactFrequency:{
   contactFrequency: null
}

The payload that goes when I am not inserting a value is ok, it works as I expect but whenever I insert a value it doesn't go as an object. Is there a quick/easy way to modify it as passes object to backend?

When the form filled and submitted, first handleCreate method being activated:

    handleCreate(policyDocument: PolicyDocument) {
        this.userFeedbackService.clearAllUserFeedback();
        if (this.validatePolicyDocumentDate(policyDocument)) {
            this.policyDocumentService.create(policyDocument).subscribe(
                (response) => {
                    console.log('handleCreate returned ', response);
                    this.router.navigate(['/policies'])
                        .then(() => this.userFeedbackService.clearAndAddSuccess('Policy created successfully'));
                },
                () => {
                    this.removeDefaultValidityInDays();
                    window.scrollTo({top: 0, behavior: 'smooth'});
                });
        } else {
            window.scrollTo({top: 0, behavior: 'smooth'});
        }
    }

And then it goes to service:

create(policyDocument: PolicyDocument): Observable<PolicyDocument> {
        console.log("Policy Document for frequency rule: " + policyDocument);
        console.log("Contact Frequency for frequency rule: " + policyDocument.contactFrequency?.contactFrequency);
        return this.http
            .put(POLICY_DOCUMENTS_API, policyDocument)
            .map(data => {
                this.userFeedbackService.clearAndAddSuccess('Policy document has been created successfully');
                return <PolicyDocument>data;
            })
            .catch((err) => {
                this.userFeedbackService.addError('Failed creating policyDocument');
                throw new Error(err.toString());
            });
    }

答案1

得分: 2

以下是翻译好的部分:

"当下一请求为空时,我可以看到它是可以的,因为此属性由ContactFrequency模型定义:

contactFrequency:{
   contactFrequency: null
}

...所以,当你输入内容时,输入会作为数字属性响应。这没问题!问题在于你需要在执行HTTP请求之前捕捉请求,在那个时候你需要创建对象作为contactFrequency

你可能有这样的服务:

save(data: YourModel): Observable<YourModel> {

    return this.http.post(url, data).pipe(
      catchError((err) => {
        ... 代码
      })
    );
  }

你需要在你的控制器中调用service.save(data),并在这里你需要构建对象如下:

const obj: PolicyDocument = {
    bla: 'bla',
    ble: 'ble',
    contactFrequency: {
        id: 'xyz',
        contactFrequency: 180
    }
}

你有值180,然后构建对象,然后调用service.save(data)

我建议使用"响应式表单",因为你可以订阅输入并构建contactFrequency模型的值。

在我看来,"模板表单"应该被弃用。"

英文:

As I can see the next request when is null is ok because this property is typed by ContactFrequency model:

contactFrequency:{
   contactFrequency: null
}

... So, when you are typing something the input is responding as number atribute. Is fine!, the problem here is that you need catch the request before the http request is executed, in that moment you need create the object as contactFrequency:

May you have service like this:

save(data: YourModel): Observable<YourModel> {

    return this.http.post(url, data).pipe(
      catchError((err) => {
        ... code
      })
    );
  }

You need to call serivce.save(data) in your controller, and here you need to buid the object like this:

const obj: PolicyDocument = {
    bla: 'bla',
    ble: 'ble',
    contactFrequency: {
        id: 'xyz',
        contactFrequency: 180
    }
    
}

You have the value 180, then build the object, then call service.save(data)

My recomendation is to use reactive forms, because you can subscribe to the input and buid the value of contactFrequency model

In my opinion template forms must be deprecated.

huangapple
  • 本文由 发表于 2023年4月4日 05:44:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/75923995.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定