更改Aurelia中的数组顺序,奇怪的行为

时间:2016-10-11 04:34:03

标签: javascript aurelia

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

  1. 输入输入似乎未被识别为Aurelia更新项目的更改
  2. 在页面加载后输入/更改一个项目然后通过这些方法更改其在数组中的位置时,项目的索引似乎丢失(变为-1)。如果未通过输入字段更改项目,则可正确识别数组中的索引并进行排序。
  3. 数组,绑定甚至子元素是否存在任何已知问题?为获得理想的行为而接受过测试的战斗是什么?非常感谢!

    父元素

    ...   
    <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)
      }
    
    }
    

2 个答案:

答案 0 :(得分:3)

repeat.for有几个可以利用的上下文变量。 [Documentation]

Gist演示: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 :(得分:1)

我认为这与字符串的不变性有关。也就是说,不能修改字符串,因此当您修改文本框中的值时,实际上会替换数组元素而不是修改数组元素。这就是你失去约束力的原因。

这是一个要点,它证明了在绑定到对象列表时它能正常工作。

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