简体   繁体   中英

Issues Passing Array to Custom HTML Component - Aurelia Framework

I've spent a good bit of time playing around with this, and haven't been find similar problems such as this, though I'm sure it has had to have came up.

I'll try to give a brief summary of what I'm trying to do and the issue and then provide relevant code. I have a form with a dynamic form inputs. The form inputs are coming from a custom HTML I made. There are a few inputs in this element, one being a select input with options from a passed array. I've done a similar select option in other parts of this project, and I've even been able to create the select input within the main HTML portion of my page and not the custom component.

So, I think I narrowed down that it must be how I am passing the array to the HTML. I've seen that camelCase it is preferred to use came-case when passing binding properties to elements. However, my variable is not camel cased. It is called 'glaccounts'. I have tried adding dashes though: g-laccounts, gl-accounts, gl-accounts. None of which have worked. I've tried switching to just 'accounts' and still no luck. It just tells me 'glaccounts' is non repeatable.

Relevant code: (remove no relevant HTML so the tags are not present. Will do the same with the Typescript classes)

<div repeat.for="item of items">
  <div class="margin-sm-t">
    <manual-entry-inputs item-number="${item.itemNumber}" glaccounts="${item.glaccounts}" handle-remove-button.call="removeEntry(item.itemNumber)"></manual-entry-inputs>
   </div>
</div>
<button class="btn btn-xs btn-outline btn-success" data-toggle="tooltip" title="New Entry Item" click.delegate="addEntryItem()">
  <i class="fa fa-plus fa-1x"></i>
</button>

The above is apart of the overall form. A repeat.for is being used on an array called items. Each item has a manual-entry-inputs custom element with an itemNumber, glaccounts, and a callback function passed. Issue I believe at glaccounts="${item.glaccounts}". The Button below it adds entry to this form.

export class ManualEntry {
    public itemCount: number = 2;
    public items: ManualEntryInputs[] = [];
    public glaccounts: Models.IGLAccountMessage[] = [];
    public glaccountRequest: Models.IGLAccountQueryRequest = {};
    constructor(private glaccountList: Api.GLAccountList,
        private router: ControllerService) {
    }

    public activate = () => {
        this.glaccountList.get(this.glaccountRequest).then(this.loadGLAccountList);
    }

    public loadGLAccountList = (response: Models.IGLAccountQueryResponse) => {
        if (response.isOk) {
            this.glaccounts = response.data;
            let manualEntryInputs = new ManualEntryInputs(this.itemCount - 1, this.glaccounts);
            this.items.push(manualEntryInputs);

            manualEntryInputs = new ManualEntryInputs(this.itemCount, this.glaccounts);
            this.items.push(manualEntryInputs);
            console.log(this.items)
        }
    }

    public addEntryItem = () => {
        this.incrementItemCount();
        let newManualEntryInputs = new ManualEntryInputs(this.itemCount, this.glaccounts);
        this.items.push(newManualEntryInputs);
    }
}

This is the Typescript class behind the overall form. Aurelia framework calls activate() and there I grab the accounts from my API. Two manual input objects are declared both being pushed into the array items with the itemCount and the newly grabbed accounts. The addEntry is there for the purpose of showing it's the same glaccounts variable being passed into the ManualEntryInputs object. I can confirm via console logs that this glaccounts holds the array I want to pass. As stated I have a working select input within the main page (not the custom element) using this same array.

<div class="col-sm-1">
  <label class="h5">Item ${itemNumber}</label>
</div>
<div class="col-sm-2">
  <select class="form-control" name="accountId" value.bind="accountId">
    <option value="null">Choose...</option>
    <option repeat.for="glaccount of glaccounts" model.bind="glaccounts.id">
      ${glaccounts.name}
    </option>
  </select>
</div>

This is within the manual entry input component. Same code I have used in place in the main page. I included itemNumber to show how I use that value because it does work and display what I am expecting, just not the arry.

export class ManualEntryInputs {
    @bindable itemNumber: number;
    @bindable account: string;
    @bindable reference: string;
    @bindable amount: number;
    @bindable date: Date;
    @bindable memo: string;
    @bindable handleRemoveButton: Function;
    @bindable glaccounts: Models.IGLAccountMessage[];
    journalEntryDetail: GLJournalEntryDetail;

    constructor(itemNumber: number, glaccounts: Models.IGLAccountMessage[]) {
        this.itemNumber = itemNumber;
        this.glaccounts = glaccounts;
        console.log(glaccounts);
        console.log("In manual input constructor");
        console.log(this.glaccounts);
        console.log(this.itemNumber);
    }

    public activate = () => {
        console.log("Inn Activate")
        console.log(this.glaccounts);
    }
}

Finally, the TS class for the manual entry inputs. The console output, when the objects are declared in the other TS file, when activate and addEntry is called, they have the expected values I want. I assume when they are getting created on the page that may get called again because I get some other console output of a BindingEngine JSON object for this.glaccounts and the actual HTML for this.itemNumber.

If anyone has had similar experiences I'd be grateful to know how you came to the resolution, or if anyone has any information that could point me in the right direction that would also be very appreciated! Thanks for any insight.

You shouldn't use string interpolation when binding to your bindable properties here, this would simply pass a string and break the binding chain

<manual-entry-inputs item-number="${item.itemNumber}" glaccounts="${item.glaccounts}"

Try this instead:

<manual-entry-inputs item-number.bind="item.itemNumber" glaccounts.bind="item.glaccounts"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM