2015-04-26 77 views
2

我已經設法創建了一個使用boostrap-select元素的自定義元素。但是,我可以從主視圖(父級)傳遞/綁定值,但是當我使用雙向綁定時,我無法從元素中獲取選擇。雙向綁定不能在aurelia的引導選擇上工作

我的定製元素是:

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用選擇控件進行選擇,如下所示,使用雙向命令:

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

但是,p.selectedValue沒有變化。

任何想法爲什麼這不起作用?

+0

我已經得到了這個工作,沒有'bootstrap-select'使用我自己的自定義元素。 ''。它看起來和你很相似,只不過當我用'click.delegate =「選擇(item)」'選擇改變時,我只是綁定。我確實想嘗試整合引導選擇,所以我會嘗試 – Charleh

+0

感謝您的答覆。你能看到雙向綁定有什麼問題嗎?我甚至嘗試綁定'tempvar',認爲導航像p.selectedValue這樣的對象結構可能是一個問題,但我有同樣的問題。 –

回答

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,所以它絕對是值得注意的事情

+0

非常感謝。失去了幾個小時看着這個,但加上我正在這個驚人的框架學習如此之多。 –

+0

我最終爲此使用了一個自定義元素 - 它看起來幾乎完全相同,它只是幾行代碼(Aurelia的力量!) – Charleh

+0

是否有可能看到你是如何做到這一點的?再次感謝。 –

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