双向绑定不能在bootstrap上工作 - 选择aurelia

时间:2015-04-26 20:43:45

标签: aurelia

我设法创建了一个自定义元素来使用boostrap-select元素。但是,我可以从主视图(父级)传递/绑定值,但是当我使用双向绑定时,我无法从元素中获取选择。

我的自定义元素是:

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控件进行选择时更改,如下所示,使用双向命令:

 selected-value.two-way="p.selectedValue"

但是,p.selectedValue没有改变。

为什么这不起作用?

2 个答案:

答案 0 :(得分:2)

原来是一个简单的范围问题:

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,所以它肯定值得注意

答案 1 :(得分:0)

以下代码适用于我,以防任何人遇到相同问题:

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