2016-10-11 3 views
0

私は単純なリストを管理し、アイテムの名前を変更し、その順序を変更するカスタム要素を構築しようとしています。残念ながら、実際にはピン止めするのは難しい奇妙な動作に気付いています。アウレリアの配列順序を変えて、奇妙な振る舞い

  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

  • 現在のアイテムの正しい位置ではなくitems.indexOf(item)$indexコンテキスト変数を使用することによって決定することができます。
  • データ入力値は、itemitems.slice(newIndex, item)に渡すことで保存されます。

アレイの変更を監視する必要がある場合は、CollectionObserverがそれに最適です。詳細はこちら:Observing Objects and Arrays in Aurelia

<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> 
するlist.html

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

} 

1

これは文字列の不変性と関係があります。つまり、文字列を変更することはできません。そのため、テキストボックス内の値を変更すると、配列要素は実際には変更されずに置き換えられます。だからあなたは縛りを失っているのです。

ここでは、オブジェクトのリストにバインドするときに正しく動作することを示す要点を示します。

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