Call function from custom element

Havig the following custom element:

@inlineView(`
<template>
    <div class="row">
        <div class="col-md-2" if.bind="withSizeLimit">
            <div class="input-group">
                 <input type="text"
                        value.bind="size"
                        style="text-align: center;"
                        class="form-control form-control-sm"
                        />
                <div class="input-group-append">
                    <button class="btn btn-sm btn-primary" type="button" click.delegate="reload()">
                        <i class="fa fa-refresh" aria-hidden="true"></i>
                     </button>
                </div>
            </div>
            <small id="" class="form-text text-muted">Anzahl d. Elemente</small>
        </div>
        <div class="col-md-10">
          <nav aria-label="pagination">
                <ul class="pagination justify-content-end">
                     <li class="page-item"><a class="page-link" tabindex="-1" click.delegate="previous()"><</a></li>
                     <li class="page-item"><input type="text" class="page-link" style="width: 50px; text-align: center;" change.delegate="reload()" value.bind="page" /></li>
                     <li class="page-item"><a class="page-link" click.delegate='next()'>></a></li>
                </ul>
           </nav>
        </div>
     </div>
  </template>
`)
@autoinject
@customElement("pagination")
export class Pagination {
    @bindable withSizeLimit: Boolean;
    @bindable({ defaultBindingMode: bindingMode.twoWay }) page: number = 1;
    @bindable({ defaultBindingMode: bindingMode.twoWay }) size: number = 10;
    @bindable loadFunction;
    @bindable maxPages: number = 10;
    @bindable maxSize: number = 40;
    

    public constructor(
        private element: Element
    ) {
        
    }

    attached() {
    }

    public reload() {
        
        this.loadFunction(this.page, this.size);
    }

    public next() {
        this.page = ++this.page;
        if (this.page >= this.maxPages) this.page = this.maxPages;
        this.loadFunction(this.page, this.size);

    }

    public previous() {
        if (this.page > 1) {
            this.page = --this.page;
            this.loadFunction(this.page, this.size);
        }
    }
}

And the following template snippet:

<pagination with-size-limit.bind="true"
                        size.bind="size"
                        page.bind="page"
                        max-pages.bind="10"
                        max-size.bind="40"
                        load-function.call="LoadIndex(page, size)"
                        containerless></pagination>

and finally the following class:

public LoadIndex() {
        console.log(page + " " + size);
        if (this.size > 40) this.size = 40;
        if (this.size < 1) this.size = 1;
        if (this.page > 10) this.page = 10;
        if (this.page < 1) this.page = 1;
        this.index= [];
        this.Client.getIndex(page, size)
            .then((Index: IndexItem[]) => {
                this.Index =Index;
            })
            .catch(err => {
    
            });
    }

Now my problem is, that the “next”-button of my custom element doesn’t work. It is always one number behind the “new” value. when I enter the digits directly into the input field, everything works fine. I guess this is a timing problem of calling the “Next()” method from the custom element.
It seems that the function is called before the binded value “page” or “size” is updated.

Can anyone help me?

Change

to:

this.page++;

Thanks for the reply. Unfortunatly this doesn’t solves the problem.

E.g. when I’m on page 2 and click next, then page 2 gets forwarded in request instead of 3.
A console.log in the custom element shows the correct data. In the parent method not :confused:

It seems that the function is triggered before the parent gets informed about the value change.

Sorry. Took a quick stab. Now that I had time to look closer, it appears you need to call:

this.loadFunction(this.page, this.size);

like this:

this.loadFunction({page: this.page, size: this.size});

See Binding Basics > Function References for the details.

2 Likes

Great. So many thanks. That did it for me.

Glad it worked. :grin: