双向绑定不适用于 bootstrap-select with aurelia
Two way binding not working on bootstrap-select with aurelia
我已经成功地创建了一个自定义元素来使用 boostrap-select 元素。但是,我可以从主视图(父视图)为它 pass/bind 值,但是当我使用双向绑定时,我无法从元素中获取 selection。
我的自定义元素是:
import {inject, customElement, bindable} from 'aurelia-framework';
import * as selectpicker from 'bootstrap-select'
@customElement('select-picker')
export class BootStrapSelectPicker {
@bindable selectableValues = null;
@bindable newValue = null;
@bindable selectedValue = 10;
constructor(){
}
attached(){
$('.selectpicker').selectpicker({
style: 'btn-info',
size: 4
});
$('.selectpicker').on('change', function(){
var selected = $(this).find("option:selected").val();
this.selectedValue = selected;
console.log(this.selectedValue);
});
$('.selectpicker').val(this.selectedValue); <-- the selection here is correct
$('.selectpicker').selectpicker('refresh');
}
}
对应的视图为:
<template>
<select class="selectpicker">
<option repeat.for="p of selectableValues">${p}</option>
</select>
</template>
我使用自定义元素的包含视图是:
<template>
<require from="./select-picker"></require>
<ul class="list-group">
<li class="list-group-item" repeat.for="p of messageProperties">
<div if.bind="p.propertyType == 'string'">
<div class="form-group">
<label for="ln">Name: ${p.propertyName}</label>
<input type="text" value.bind="p.propertyValue" class="form-control" id="ln" >
</div>
</div>
<div if.bind="p.propertyType == 'integer'">
<div class="form-group">
<label for="ln">Name: ${p.propertyName}</label>
<input type="text" value.bind="p.selectedValue" class="form-control" id="ln" >
<select-picker selectable-values.bind="p.selectableValues"
selected-value.two-way="p.selectedValue"></select-picker>
</div>
</div>
</li>
</ul>
</template>
我预计 p.selectedValue 会在使用 select 控件生成 selection 后发生变化,如下所示,使用双向命令:
selected-value.two-way="p.selectedValue"
但是,p.selectedValue 没有改变。
知道为什么这不起作用吗?
原来是一个简单的范围问题:
attached(){
$('.selectpicker').selectpicker({
style: 'btn-info',
size: 4
});
$('.selectpicker').on('change', function(){
var selected = $(this).find("option:selected").val();
this.selectedValue = selected; // <-- This here doesn't refer to the VM any more
// if you look at the line above you are wrapping $(this) with jq, this works
// because 'this' is now in the scope of the calling element but
// doesn't refer to the aurelia viewmodel
console.log(this.selectedValue);
});
$('.selectpicker').val(this.selectedValue);
$('.selectpicker').selectpicker('refresh');
}
简单的修复是:
attached(){
var self = this; // <--- Create a ref to the VM
$('.selectpicker').selectpicker({
style: 'btn-info',
size: 4
});
$('.selectpicker').on('change', function(){
var selected = $(this).find("option:selected").val();
// Change this to self
self.selectedValue = selected; // <--- Correct object gets the value now - binding works
console.log(this.selectedValue);
});
$('.selectpicker').val(this.selectedValue);
$('.selectpicker').selectpicker('refresh');
}
我不确定这在 ES6/7 中将如何实际处理 - 我确定我在某处读到过 this
将如何改变,但由于您正在转换为 ES5,这绝对是注意
以下代码对我有用,以防有人遇到同样的问题:
import {inject, customElement, bindable} from 'aurelia-framework';
import 'bootstrap-select'
@customElement('select-picker')
@inject(Element)
export class BootStrapSelectPicker {
@bindable name: string;
@bindable selectableValues;
@bindable selectedValue;
constructor(private element) {
}
attached() {
var self = this;
var $: any = jQuery;
var $elm = $(self.element).find('select');
if ($elm.length > 0) {
$elm.selectpicker();
$elm.on('change', function () {
self.selectedValue = $(this).find("option:selected").val();
});
this.refreshPicker($elm);
}
}
selectedValueChanged(newValue, oldValue) {
var $: any = jQuery;
var $elm = $(this.element).find('select');
this.refreshPicker($elm);
}
private refreshPicker = ($elm) => {
$elm.val(this.selectedValue);
$elm.selectpicker('refresh');
}
}
我已经成功地创建了一个自定义元素来使用 boostrap-select 元素。但是,我可以从主视图(父视图)为它 pass/bind 值,但是当我使用双向绑定时,我无法从元素中获取 selection。
我的自定义元素是:
import {inject, customElement, bindable} from 'aurelia-framework';
import * as selectpicker from 'bootstrap-select'
@customElement('select-picker')
export class BootStrapSelectPicker {
@bindable selectableValues = null;
@bindable newValue = null;
@bindable selectedValue = 10;
constructor(){
}
attached(){
$('.selectpicker').selectpicker({
style: 'btn-info',
size: 4
});
$('.selectpicker').on('change', function(){
var selected = $(this).find("option:selected").val();
this.selectedValue = selected;
console.log(this.selectedValue);
});
$('.selectpicker').val(this.selectedValue); <-- the selection here is correct
$('.selectpicker').selectpicker('refresh');
}
}
对应的视图为:
<template>
<select class="selectpicker">
<option repeat.for="p of selectableValues">${p}</option>
</select>
</template>
我使用自定义元素的包含视图是:
<template>
<require from="./select-picker"></require>
<ul class="list-group">
<li class="list-group-item" repeat.for="p of messageProperties">
<div if.bind="p.propertyType == 'string'">
<div class="form-group">
<label for="ln">Name: ${p.propertyName}</label>
<input type="text" value.bind="p.propertyValue" class="form-control" id="ln" >
</div>
</div>
<div if.bind="p.propertyType == 'integer'">
<div class="form-group">
<label for="ln">Name: ${p.propertyName}</label>
<input type="text" value.bind="p.selectedValue" class="form-control" id="ln" >
<select-picker selectable-values.bind="p.selectableValues"
selected-value.two-way="p.selectedValue"></select-picker>
</div>
</div>
</li>
</ul>
</template>
我预计 p.selectedValue 会在使用 select 控件生成 selection 后发生变化,如下所示,使用双向命令:
selected-value.two-way="p.selectedValue"
但是,p.selectedValue 没有改变。
知道为什么这不起作用吗?
原来是一个简单的范围问题:
attached(){
$('.selectpicker').selectpicker({
style: 'btn-info',
size: 4
});
$('.selectpicker').on('change', function(){
var selected = $(this).find("option:selected").val();
this.selectedValue = selected; // <-- This here doesn't refer to the VM any more
// if you look at the line above you are wrapping $(this) with jq, this works
// because 'this' is now in the scope of the calling element but
// doesn't refer to the aurelia viewmodel
console.log(this.selectedValue);
});
$('.selectpicker').val(this.selectedValue);
$('.selectpicker').selectpicker('refresh');
}
简单的修复是:
attached(){
var self = this; // <--- Create a ref to the VM
$('.selectpicker').selectpicker({
style: 'btn-info',
size: 4
});
$('.selectpicker').on('change', function(){
var selected = $(this).find("option:selected").val();
// Change this to self
self.selectedValue = selected; // <--- Correct object gets the value now - binding works
console.log(this.selectedValue);
});
$('.selectpicker').val(this.selectedValue);
$('.selectpicker').selectpicker('refresh');
}
我不确定这在 ES6/7 中将如何实际处理 - 我确定我在某处读到过 this
将如何改变,但由于您正在转换为 ES5,这绝对是注意
以下代码对我有用,以防有人遇到同样的问题:
import {inject, customElement, bindable} from 'aurelia-framework';
import 'bootstrap-select'
@customElement('select-picker')
@inject(Element)
export class BootStrapSelectPicker {
@bindable name: string;
@bindable selectableValues;
@bindable selectedValue;
constructor(private element) {
}
attached() {
var self = this;
var $: any = jQuery;
var $elm = $(self.element).find('select');
if ($elm.length > 0) {
$elm.selectpicker();
$elm.on('change', function () {
self.selectedValue = $(this).find("option:selected").val();
});
this.refreshPicker($elm);
}
}
selectedValueChanged(newValue, oldValue) {
var $: any = jQuery;
var $elm = $(this.element).find('select');
this.refreshPicker($elm);
}
private refreshPicker = ($elm) => {
$elm.val(this.selectedValue);
$elm.selectpicker('refresh');
}
}