2017-03-20 40 views
1

我正在Aurelia中構建一個多步驟表單,每個頁面顯示一個問題。只有null或數組實例可以綁定到多選

我對每個問題都使用相同的視圖,並使用if語句確定要顯示的表單類型字段。

當我嘗試將我的問題數據綁定到多選元素時,Aurelia會拋出錯誤並說「只有null或Array實例可以綁定到多選。」。

真奇怪的是,如果第一個問題是一個多重選擇,我不會收到錯誤,直到我來到一個非多選問題,然後回到多選問題。

我可以通過爲此路線設置activationStrategy: 'replace'來解決整個問題,但我真的不希望這樣。

重要的代碼如下:

import {inject} from 'aurelia-framework'; 
import {Router} from 'aurelia-router'; 

@inject(Router) 
export class Form { 
    constructor (router) { 
    this.router = router; 
    this.active = 0; 
    this.field = null; 
    this.fields = [ 
     { 
     type: 'text', 
     value: null 
     }, 
     { 
     type: 'select', 
     value: [], 
     options: [ 
      'foo', 
      'bar' 
     ] 
     }, 
     { 
     type: 'select', 
     value: [], 
     options: [ 
      'foo', 
      'bar' 
     ] 
     }, 
     { 
     type: 'text', 
     value: null 
     }, 
    ]; 
    } 

    activate (routeParams) { 
    this.active = routeParams.fieldIndex || 0; 
    this.active = parseInt(this.active); 
    this.field = this.fields[this.active]; 
    } 

    prev() { 
    if (typeof this.fields[this.active - 1] !== 'undefined') { 
      this.router.navigateToRoute('form', { 
       fieldIndex: this.active - 1 
      }); 

      return true; 
     } 
     else { 
      return false; 
     } 
    } 

    next() { 
    if (typeof this.fields[this.active + 1] !== 'undefined') { 
      this.router.navigateToRoute('form', { 
       fieldIndex: this.active + 1 
      }); 

      return true; 
     } 
     else { 
      return false; 
     } 
    } 
} 

而且模板:

<template> 
    <div class="select" if.bind="field.type == 'select'"> 
    <select value.bind="field.value" multiple="multiple"> 
     <option repeat.for="option of field.options" value.bind="option">${option}</option> 
    </select> 
    </div> 

    <div class="text" if.bind="field.type == 'text'"> 
    <input type="text" value.bind="field.value"> 
    </div> 

    <a click.delegate="prev()">Previous</a> | <a click.delegate="next()">Next</a> 
</template> 

但你可能會想檢查出GistRun:https://gist.run/?id=4d7a0842929dc4086153e29e03afbb7a,以獲得更好的理解。

嘗試將第一個問題設置爲多選,並且您會注意到錯誤消失(直到您回到它)。您也可以在app.js中嘗試activationStrategy,如上所述。

爲什麼會發生這種情況,我該如何解決?

另請注意,在我的真實應用程序中,我實際上使用compose而不是if s,但已嘗試使用這兩種方法,兩者都產生相同的錯誤。看起來好像選擇值在if被評估之前被綁定,導致錯誤出現,因爲text字段類型缺少options數組。

+0

我認爲這個問題歸結於在''到一個空的測試數組(不在一個對象內)並且工作。我在'activate()'函數中加入了'console.log(this.field.value)'。最終 - 所討論的數組開始包含「[__array_observer__:ModifyArrayObserver]」 - 在這一點上,它會崩潰。看起來它不再是一個足夠簡單的Array。 – Tom

回答

0

好了,所以它原來調換HTML的順序,並把selectinput解決了這個問題。

傑里米Danyow解釋它是這樣的:

當Form.field變化,訂閱該屬性的更改綁定順序評估。這意味着有一段時間,選擇AND輸入都在頁面上。 html input元素將空值賦值爲空字符串,這反過來導致field.value爲空字符串,這使得多選投擲。

非常棘手的跟蹤imo,但我很高興Aurelia開發者在Github上如此有用。

工作要點是:https://gist.run/?id=3f88b2c31f27f0f435afe14e89b13d56

1

晚了一點,但我想給一個建議 - 爲SELECT多選擇,你應該從多選擇去耦約束變量,以避免這些錯誤。

例如,如果你在一個綁定到「選擇」自定義元素,應結合:

<select multiple value.two-way="selectedDecoupled">

然後,當自定義「選擇」的變化,它只是改變實際變量元件如果綁定的值是數組:

:它在用自定義SELECT2元件使用

selectedChanged(newV, oldV){ 
    if(typeof newV =='object') 
     this.selectedDecoupled = newV; 
    else 
     this.selectedDecoupled = []; 
    $(this.SELECT).val(this.selectedDecoupled).trigger('change'); 
} 

實施例

相關問題