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

  • 현재 항목의 정확한 위치가 $index 상황에 맞는 변수를 사용하는 대신 items.indexOf(item)에 의해 결정될 수있다.
  • 데이터 입력 값은 itemitems.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

관련 문제