drakid
drakid

Reputation: 320

Cannot call function in view model from <content> element

When I click button #btn1 or #btn2 Save, the console says that:

Uncaught Error: save is not a function
    getFunction @ aurelia-binding.js:1971
    evaluate @ aurelia-binding.js:1565
    callSource @ aurelia-binding.js:4989
    (anonymous function) @ aurelia-binding.js:5013
    handleDelegatedEvent @ aurelia-binding.js:3211

But the outter button #btn3 works fine. I also try $parent.save() in #btn2 but it's not work. Any idea?

app.html

<create-location contact.two-way="contact" working-time.two-way="workingTime">
    <require from="dist/component/working-time"></require>
    <working-time title="Working Time" view-model.ref="workingTime"></working-time>
    <require from="dist/component/contact"></require>
    <contact title="Contact" phone="123" email="[email protected]" fax="123456" view-model.ref="contact"></contact>

    <button id="btn1" type="button" click.delegate="save()">Save (=>error<=)</button>
    <button id="btn2" type="button" click.delegate="$parent.save()">Save (=>error also<=)</button>
</create-location>

create-location.html

<template>
    <button id="btn3" type="button" click.delegate="save()">Save (=>it works<=)</button>
    <content></content>
</template>

create-location.js

import {bindable} from 'aurelia-framework'

export class CreateLocationCustomElement {
    @bindable contact;
    @bindable workingTime;

    save() {
        alert("save");
    }
}

Update I tried Fabio's suggest and it works.

Another question: Look at aurelia dialog, they call testDelegate function of view-model inside <content> element similar to my case. They don't use view-model.ref. I take a look at the source code but I don't find out where they process that call. Maybe I miss out some point or are there conventions here. Does anyone know how they do that?

Upvotes: 4

Views: 611

Answers (1)

Fabio
Fabio

Reputation: 11990

You could put the create-location's view-model in a property, using view-model.ref, and then use that property to call save(). Like this:

<create-location view-model.ref="createLocationVM" contact.two-way="contact" working-time.two-way="workingTime">
    <require from="dist/component/working-time"></require>
    <working-time title="Working Time" view-model.ref="workingTime"></working-time>
    <require from="dist/component/contact"></require>
    <contact title="Contact" phone="123" email="[email protected]" fax="123456" view-model.ref="contact"></contact>

    <button id="btn1" type="button" click.delegate="createLocationVM.save()">Save (=>error<=)</button>

</create-location>

Nevertheless, I think it would be better if you recreate the whole component. There's no need to use <require> inside the component's content, and perhaps you could put the second save button in the create-location's view.

Upvotes: 1

Related Questions