2016-10-11 67 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