Aurelia自定义元素中的2种方式数据绑定-将自定义元素绑定到父视图模型 [英] 2 way databinding in Aurelia custom elements - bind custom element to parent viewmodel

查看:65
本文介绍了Aurelia自定义元素中的2种方式数据绑定-将自定义元素绑定到父视图模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我做了很多服务",可以将这些服务注入到我的视图模型中,以节省som冗余和时间.

现在,我希望将其进一步发展,并制作那些表单元素(选择,文本,复选框-初学者的选择下拉列表)并将其转变为自定义元素,仅将服务注入到自定义元素中./p>

我可以使它在某种程度上起作用.在父"视图中需要时显示自定义元素(在这种情况下为select),但是当我更改自定义选择元素的选定值时,它不绑定到父"视图模型,这是我的要求

我希望能够通过其模板中的bind属性将我从自定义元素中选择的值绑定到父"视图模型上的属性.

我将在几分钟内更新一个小代码段.

create.js(我称为父视图模型)

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

create.html(父视图)

<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();
    }
}

发生的事情是,最初create.html视图输出初始值",并且当我更改自定义元素select的值时,新选择的值会发出警报,但不会更新绑定的父变量,即仍然只显示初始值".

解决方案

这里有两个问题:

  1. 由于不区分大小写,您需要对DOM中的所有属性名称进行大小写

    selected-value.bind="property"

    不是

    selectedValue.bind="property"

  2. 您需要双向绑定.使用装饰器创建@bindable时,其中一个参数是BindingMode,可用于设置默认的绑定模式.

    Aurelia设置了一些合理的默认值,例如input value.bind=".."的默认设置是两种方式,无需明确显示

    如果您不想设置默认的绑定模式,则可以通过绑定来明确显示:

    selected-value.two-way="prop"

希望这会有所帮助:)

我认为在回答此问题后,API发生了一些变化.

@bindable装饰器具有以下信号:

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

文档中的Aurelia备忘单是检查快速参考的最佳位置之一:

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

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".

解决方案

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

这篇关于Aurelia自定义元素中的2种方式数据绑定-将自定义元素绑定到父视图模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆