2017-03-20 24 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'); 
} 

实施例

相关问题