2016-10-11 76 views
0

我正在尝试构建一个自定义元素来管理简单列表,重命名项目并更改其顺序。不幸的是,我注意到一些奇怪的行为,实际上很难确定。在Aurelia中更改数组顺序,怪异行为

  1. 键入到输入似乎没有被识别为改变用于奥里利亚更新项目
  2. 当输入/改变页面加载之后的一个项,并且然后经由这些方法改变阵列的位置,的指数该项目似乎丢失(变成-1)。如果项目没有通过输入字段更改,则数组中的索引被正确识别并进行排序。

是否有任何已知的问题数组,绑定,甚至可能是子元素?为了获得理想的行为,接受测试的测试是什么?非常感谢!

父元素

... 
<list items.bind="list"></list> 
... 

列表元素

<template> 
<div class="input-group" repeat.for="item of items"> 
    <input value.bind="item" class="input" type="text" placeholder="Item" autofocus> 
    <a click.delegate="deleteItem(item)">X</a> 
    <a click.delegate="moveItemUp(item)">^</a> 
    <a click.delegate="moveItemDown(item)">v</a> 
</div> 
<a click.delegate="addItem()">Add Item</a> 

名单JS

export class List { 

    @bindable({defaultBindingMode: bindingMode.twoWay}) items; 

    constructor() {} 

    addItem() { 
    this.items.push('new') 
    } 

    deleteItem(item) { 
    let i = this.items.indexOf(item) 
    this.items.splice(i, 1) 
    } 

    moveItemUp(item) { 
    let i = this.items.indexOf(item) 
    if (i === 0) return 
    let temp = item 
    this.items.splice(i, 1) 
    this.items.splice(i - 1, 0, temp) 
    } 

    moveItemDown(item) { 
    let i = this.items.indexOf(item) 
    if (i === this.items.length) return 
    let temp = item 
    this.items.splice(i, 1) 
    this.items.splice(i, 0, temp) 
    } 

} 

回答

3

repeat.for有几个语境变量,你可以利用的。 [Documentation]

吉斯特演示:https://gist.run/?id=1c8f78d8a774cc859c9ee2b1ee2c97f3

  • 当前项目的正确位置,可以通过使用$index情境变量,而不是items.indexOf(item)确定。
  • 通过将item传递给items.slice(newIndex, item)可以保留输入的数据绑定值。

如果您需要观察数组更改,CollectionObserver可能非常适合这一点。更多细节在这里:Observing Objects and Arrays in Aurelia

list.js

import { bindable, bindingMode } from 'aurelia-framework'; 

export class List { 

    @bindable({defaultBindingMode: bindingMode.twoWay}) items; 

    constructor() {} 

    addItem() { 
    this.items.push(`New Item ${this.items.length + 1}`); 
    } 

    deleteItem(i) { 
    this.items.splice(i, 1); 
    } 

    moveItemUp(i, item) { 
    if (i === 0) 
     return; 

    this.moveItem(i, i - 1, item); 
    } 

    moveItemDown(i, item) { 
    if (i === this.items.length - 1) 
     return; 

    this.moveItem(i, i + 1, item); 
    } 

    moveItem(oldIndex, newIndex, item) { 
     this.items.splice(oldIndex, 1); 
     this.items.splice(newIndex, 0, item); 
    } 

} 

list.html

<template> 
    <div class="input-group" repeat.for="item of items"> 
     <input value.bind="item" class="input" type="text" placeholder="Item" autofocus> | 
     <a click.delegate="deleteItem($index)"><i class="fa fa-close"></i></a> | 
     <a click.delegate="moveItemUp($index, item)"><i class="fa fa-arrow-up"></i></a> | 
     <a click.delegate="moveItemDown($index, item)"><i class="fa fa-arrow-down"></i></a> 
    </div> 
    <a click.delegate="addItem()">Add Item</a> 
</template> 
1

我相信这与字符串的不变性有关。也就是说,字符串不能被修改,所以当你在文本框中修改一个值时,数组元素实际上被替换而不是被修改。这就是为什么你失去了约束力。

这里有一个要点,它演示了当绑定到对象列表时它可以正常工作。

https://gist.run/?id=22d186d866ac08bd4a198131cc5b4913