2 way databinding in Aurelia custom elements - bind custom element to parent viewmodel

ⅰ亾dé卋堺 提交于 2019-12-01 14:37:58

问题


In my application I have made a lot of "services" which I can inject in my viewmodels to save som redundancy and time.

Now I'm looking to take it 1 step further, and make those form elements (select, text, checkboxes - a select dropdown for starters) and turn them into custom elements, injecting the service in only the custom element.

I can get it working to some extent. The custom element (select in this case) is showing when I require it in the "parent" view, however when I change the selected value of the custom select element, it does not bind to the "parent" viewmodel, which is my requirement.

I want to be able to bind my selected value from the custom element to a property on the "parent" viewmodel via the bind attribute in it's template.

I'll update which a little code snippet in a few minutes.

create.js (what I refer to as parent viewmodel)

import {bindable} from 'aurelia-framework';
export class Create{
    heading = 'Create';
    @bindable myCustomElementValue = 'initial value';
}

create.html (parent view)

<template>
    <require from="shared/my-custom-element"></require>
    <my-custom selectedValue.bind="myCustomElementValue"></my-custom>
    <p>The output of ${myCustomElementValue} should ideally be shown and changed here, as the select dropdown changes</p>
</template>

my-custom.js

import { inject, bindable} from 'aurelia-framework';
import MyService from 'my-service';

@inject(MyService )
export class MyCustomCustomElement {
    @bindable selectedValue;

    constructor(myService ) {
        this.myService = myService ;
    }

    selectedValueChanged(value) {
        alert(value);
        this.selectedValue = value;
    }

    async attached() {
        this.allSelectableValues = await this.myService.getAllValues();
    }
}

What happens is initially the create.html view outputs "initial value", and as I change the value of the custom element select, the newly selected value gets alerted out, but it does not update the bound parent variable, which is still just displaying "initial value".


回答1:


There are a couple of issues here:

  1. You need to kebab-case any property names in the DOM due to case-insensitivity

    selected-value.bind="property"

    not

    selectedValue.bind="property"

  2. You need to bind two-way. When creating a @bindable using the decorator, one of the arguments is BindingMode which you use to set the default binding mode.

    Aurelia sets some sensible defaults, e.g. the default for input value.bind=".." is two way without being explicit

    If you don't want to set a default binding mode, you can just be explicit with your binding:

    selected-value.two-way="prop"

Hope this helps :)

Edit: I think the API changed a little after this answer.

The @bindable decorator has the following sig:

bindable({
  name:'myProperty',
  attribute:'my-property',
  changeHandler:'myPropertyChanged',
  defaultBindingMode: bindingMode.oneWay,
  defaultValue: undefined
})

One of the best places to check for quick reference is the Aurelia cheat-sheet in the docs:

http://aurelia.io/docs/fundamentals/cheat-sheet



来源:https://stackoverflow.com/questions/33297363/2-way-databinding-in-aurelia-custom-elements-bind-custom-element-to-parent-vie

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!