javascript - onclick 在数组之间按 Angular 移动数组项 - 包括 Plunker

标签 javascript arrays angular angular5

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

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

这是 typescript 代码,任何想在这里查看的人都可以在这里查看

//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; 规则

关于javascript - onclick 在数组之间按 Angular 移动数组项 - 包括 Plunker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48753928/

相关文章:

Javascript 按键 addEventListener

javascript - Sprite 动画问题

arrays - 你能在 Julia 中为字符串预分配空间吗?

c - 如何在C编程中将两个二维字符串数组合并为一个?

javascript - 选择多个文件

javascript - 尾随 "="在 angular2 url 中被 trim

javascript - jQuery将更多参数传递给回调

PHP JSON 编码不起作用

javascript - 通过插值引用对象中的对象(Angular 2+)

javascript - 在 AngularJS 中将函数从 Controller 移动到服务