Angular 单击时在数组之间移动数组项 - 包括 Plunkr

Angular move array items between arrays on click - Plunkr included

我想创建一个标签列表,当你点击蓝色标签时,它会被添加到一个新数组并显示在上方,它在旧数组中应该是不可选择的,但它的位置被标记为 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 {}

我会将您的数组映射到具有 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

中的 .c-seedContainer.u-displayOnly 选择器中删除了 pointer-events: none; 规则

您可以将以下代码行添加到 "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)}