单击数组之间的角度移动数组项 - 包括Plunkr

时间:2018-02-12 19:18:50

标签: javascript arrays angular angular5

我想创建一个标签列表,当你点击它添加到一个新数组的蓝色标签并显示在上面时,它应该在旧数组中不可选,但它的位置用css标记但是用户应该能够在新数组中单击它,它将返回到旧数组中的原始位置,并从新数组中删除。我已经a plunker with what I have done so far了。

到目前为止,问题是当点击它时会被添加到新阵列中,但它仍然可以在旧阵列中点击,因此多次单击它会导致向新阵列添加重复值,我还需要功能,如果用户在新数组中单击它,它将返回旧数组中的原始位置。

这里是任何想要在这里查看的人的打字稿代码

//our root app component
import {Component, NgModule, VERSION} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'

@Component({
    selector: 'my-app',
    template: `
        <div>
          <h2>Hello {{name}}</h2>
        </div>

        <p>
        Current behaviour: user clicks the blue tag and it goes into the array displayed above.
        user clicks already selected blue tag and it duplicated in array. wanted behaviour is that once selected
        it goes into the new array and it is then unclickable in the blue tags part, but you can click it from the above part and
        it will be visible and selectable in the blue part again
        </p>


        <p>
        TLDR: click blue tag and goes into another array, click tag in new array and it goes back to the blue array
        </p>

        <ul>
              <li>
                <div class="c-seedContainer u-displayOnly">
                  <span *ngFor="let m of matchArray; let i = index">{{ m }}</span> 
                </div>  
              </li>         
              <li>
                <div class="c-seedContainer u-selectionSeed">
                  <span  [class.u-removeSeed]="stateOfButton[i]" (click)="changeState(i,c)" *ngFor="let c of cloneSeedArrayForSelection; let i = index">{{ c }}</span> 
                </div>  
              </li>     
        </ul>
      `,
    })
    export class App {
      name:string;

    seed: Array<any> = [
        "ice",
        "hockey",
        "rubbish",
        "traitor",
        "mneumonic",
        "chronical",
        "stuff",
        "entity",
        "poo",
        "junk",
        "mcDonalds",
        "Fruit",
        "going",
        "sweet"
      ]

        cloneSeedArray: Array<any> = [];
        cloneSeedArrayForSelection: Array<any> = [];    

        selectedIdx = 0;
        stateOfButton: boolean[];

        matchArray: Array<any> = [];   

      constructor() {
        this.name = `Angular! v${VERSION.full}`
      }

      changeState(index, seedWord) {

        // a) click item to add / remove a class
        // b) add item to a new array
        // c) compare both arrays to ensure they match   
        // d) if both arrays dont match show warning and allow to recreate 
        // this.selectedIdx = index;
        console.log("index " + index)
        this.matchArray.push(seedWord)
        this.stateOfButton[index] = !this.stateOfButton[index];
        console.log("seedWord " + seedWord)    
      }   

    ngAfterViewInit() {
      this.cloneSeedArray = this.seed.slice();  
      this.cloneSeedArrayForSelection = this.shuffleArray( this.cloneSeedArray  )
      this.stateOfButton = Array(this.cloneSeedArrayForSelection.length).fill(false);  
      this.cd.detectChanges();
    }

    shuffleArray(d) {
        for ( let  c = d.length - 1; c > 0; c--) {
            let b = Math.floor(Math.random() * (c + 1));
            let a = d[c];
            d[c] = d[b];
            d[b] = a;
        }
        return d
    };
}

@NgModule({
    imports: [ BrowserModule ],
    declarations: [ App ],
    bootstrap: [ App ]
})
export class AppModule {}

2 个答案:

答案 0 :(得分:3)

我会将您的数组映射到具有selected属性的对象数组。

通过这种方式,我们可以轻松确定哪个元素应该在新数组中显示,哪个元素应该保留在旧数组

<强> TS

export class AppComponent {
  seed = [
    "ice",
    ...
  ];

  items: Item[];
  selectedItems: Item[] = [];

  ngOnInit() {
    this.items = this.shuffleArray(this.seed)
      .map(x => ({ name: x, selected: false }));
  }

  select(item: Item) {
    if (item.selected) {
      return;
    }

    this.selectedItems.push(item);
    item.selected = true;
  }

  unSelect(item: Item, idx: number) {
    item.selected = false;
    this.selectedItems.splice(idx, 1);
  }

 ...
}

interface Item {
  name: string;
  selected: boolean;
}

<强> HTML

<li>
  <div class="c-seedContainer u-displayOnly">
    <span *ngFor="let item of selectedItems; let i = index" (click)="unSelect(item, i)">
     {{ item.name }}
    </span> 
  </div>  
</li>         
<li>
  <div class="c-seedContainer u-selectionSeed">
    <span [class.u-removeSeed]="item.selected" (click)="select(item)" 
                        *ngFor="let item of items">
      {{ item.name }}
    </span> 
  </div>
</li>

<强> Ng-run Example

注意:我还从您的css中的pointer-events: none;选择器中删除了.c-seedContainer.u-displayOnly规则

答案 1 :(得分:1)

您可以将以下代码行添加到“changeState”方法,以了解该单词是否已存在于数组中

changeState(index, seedWord) {

// a) click item to add / remove a class
// b) add item to a new array
// c) compare both arrays to ensure they match   
// d) if both arrays dont match show warning and allow to recreate 
// this.selectedIdx = index;
for(let word of this.matchArray){
  if(word == seedWord){
    return;
  }
}
console.log("index " + index)
this.matchArray.push(seedWord)
this.stateOfButton[index] = !this.stateOfButton[index];
console.log("seedWord " + seedWord)}