Enthu
Enthu

Reputation: 532

Interpolated values does not reflect the latest values in an Angular app

The elements of dropzone1 array only reflect the initial top, left values, they do not reflect the latest top,left values.

In draw() function I push top & left values to topLeft array and finally push it to dropzone1 array inside move() function, the initial top , left values are shown but it doesn't reflect the latest current top , left values.

export class FloorZoneComponent {

    urlFloorZoneIn: any;
    roomsFloorZoneIn: any;
    existingDroppedItemZoneIn: any[] = [];
    @Input() urlFloorZone;
    @Input() roomsFloorZone;
    @Input() currentBoxFloorZone;
    @Input() existingDroppedItem: any[] = [];
    dropzone1 = [];
    currentBox?: string = this.currentBoxFloorZone;
    mouse = {
        x: null,
        y: null,
        down: false
      };
    will_draw = false;
    left;
    top;
    topLeft = [];

    @ViewChild('parentparent') parentparent; 
    
    @HostListener('mousedown', ['$event'])
    onMousedown(event) {
        this.mouse.down = true;
    }

    @HostListener('mouseup', ['$event'])
    onMouseup(event) {
        this.mouse.down = false;
    }

    documentMouseMove(e: MouseEvent) {
        // move logic
        if(!this.mouse.down) { return; }
      
        const container_rect = this.parentparent.nativeElement.getBoundingClientRect();
        this.mouse.x = e.clientX - container_rect.left;
        this.mouse.y = e.clientY - container_rect.top;
        if(!this.will_draw) {
          requestAnimationFrame(this.draw.bind(this));
          this.will_draw = true;
        }

    }

    draw() {
        this.will_draw = false;
        const { width, height} = this.parentparent.nativeElement.getBoundingClientRect();
        const perc_x = this.mouse.x / width * 100;
        const perc_y = this.mouse.y / height * 100;
        // -5 to center (elem has its width set to 10%)
        console.log('left', (perc_x - 5) + '%');
        this.left = perc_x - 5;
        this.topLeft = []
        this.topLeft.push(this.left);
        // -5 to center (elem has its height set to 10%)
        console.log('top', (perc_y - 5) + '%');
        this.top = perc_y - 5;
        this.topLeft.push(this.top)
    }

    ngOnChanges(changes: SimpleChanges) {
        if (changes.urlFloorZone && changes.urlFloorZone.currentValue) {
            this.urlFloorZoneIn = changes.urlFloorZone.currentValue;
        }
        if (changes.roomsFloorZone && changes.roomsFloorZone.currentValue) {
            this.roomsFloorZoneIn = changes.roomsFloorZone.currentValue
        }
        if(changes.existingDroppedItem && changes.existingDroppedItem.currentValue){
            this.existingDroppedItemZoneIn = changes.existingDroppedItem.currentValue;
        }        
    }


    move(box: string, toList: string[]): void { 
        box = this.currentBoxFloorZone;

        let objTemp:any = {
            pos:[]
          };
         
        objTemp.dis = this.currentBoxFloorZone;

        for(var i=0; i < this.topLeft.length; i++){
            objTemp.pos.push(this.topLeft[i]);
        }
        
        this.removeBox(box, this.dropzone1);
        toList.push(objTemp);
       
    }

    removeBox(item: string, list) {
            if (list.indexOf(item) !== -1) {
                list.splice(list.indexOf(item), 1);
            }
        
    }

    }

I call move() function and push name and top , left values to dropzone1 array

<div (mousemove)="documentMouseMove($event)" #parentparent>

  <div class="dropzone" 
       (drop)="move(currentBox, dropzone1)">

  <div class="box"
       *ngFor="let existingZone of existingDroppedItemZoneIn">
    {{ existingZone.dis }}
    <span style="display: none">{{existingZone.left}}</span>
    <span style="display: none">{{existingZone.top}}</span>
   </div>

    <div class="box"
         *ngFor="let box of dropzone1" 
         (dragStart)="currentBox = box">
    {{ box.dis.dis }}
     <span style="display: none">{{box.pos[1]}}</span>
     <span style="display: none">{{box.pos[0]}}</span>
    </div>

</div>
</div>

I am also able to log latest top , left values in console from draw() function but the *ngFor elements do not reflect the latest one

Update 1

Adding stackblitz link

Here in this link issue is in hello.component where I am assigning top,left values , in draw() and move() function.

For now I have provided box values from static array in app.component which in turn gets pushed to dropzone1 array present in hello.component where the issue is.

Update 2

I think I have figured out the issue but how to resolve this if someone could suggest.

So whenever a new box is dropped the move() function is called

(drop)="move(currentBox, dropzone1)"

from which top , left values are pushed to the box properties and interpolated to the view . Now from where the top , left values come in , they come from topleft array being created from draw() function.

So the initial top,left value gets interpolated .But when the same element is dragged again then only draw() function is called and top , left values are calculated but not get pushed, because move() function is only called when new element is dropped.

So how can I bind the interpolated data to the latest values of top,left being calculated from draw() function. Please suggest.

Upvotes: 1

Views: 203

Answers (1)

Shashank Vivek
Shashank Vivek

Reputation: 17494

This is happening because your move() is called only when a block is moved from outside the Grey area but the draw() is called for all mouse movement.

You need to update the currentBox position when it is selected and moved around.

Working demo

  draw() {
    const movingBlockIndex = (this.dropzone1.indexOf(this.currentBox));
    if (movingBlockIndex > -1) {
      this.will_draw = false;
      const { width, height } = this.parentparent.nativeElement.getBoundingClientRect();
      const perc_x = this.mouse.x / width * 100;
      const perc_y = this.mouse.y / height * 100;
      // -5 to center (elem has its width set to 10%)
      // console.log('left', (perc_x - 5) + '%');
      this.left = perc_x - 5;
      this.topLeft = []
      this.topLeft.push(this.left);
      // -5 to center (elem has its height set to 10%)
      // console.log('top', (perc_y - 5) + '%');
      this.top = perc_y - 5;
      this.topLeft.push(this.top)
      this.dropzone1[movingBlockIndex].pos[0] = (perc_x - 5);
      this.dropzone1[movingBlockIndex].pos[1] = (perc_y - 5);
    }
  }

Upvotes: 1

Related Questions