Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

View model field bound to "element.ref" is null in "attached" method for a combination of "if.bind", "repeat.for" and animations #298

Closed
Alexey1 opened this issue Aug 2, 2017 · 2 comments

Comments

@Alexey1
Copy link
Contributor

Alexey1 commented Aug 2, 2017

I'm submitting a bug report

  • Library Version:
    1.4.0

Please tell us about your environment:

  • Operating System:
    Windows 8

  • Node Version:
    6.9.2

  • NPM Version:
    4.3.0
  • JSPM OR Webpack AND Version
    Aurelia CLI 0.30.1
  • Browser:
    Chrome 60

  • Language:
    TypeScript 2.4.2

Current behavior:

  1. Create a project with au new.
  2. Add aurelia-animator-velocity as described here.

main.ts

import { Aurelia } from 'aurelia-framework'
import environment from './environment';

export function configure(aurelia: Aurelia) {
  aurelia.use
    .standardConfiguration()
    .plugin('aurelia-animator-velocity', instance => {
      instance.enterAnimation.options.duration = 1000;
      instance.leaveAnimation.options.duration = 1000;
    })
    .feature('resources');

  if (environment.debug) {
    aurelia.use.developmentLogging();
  }

  if (environment.testing) {
    aurelia.use.plugin('aurelia-testing');
  }

  aurelia.start().then(() => aurelia.setRoot());
}

app.ts

export class App {
  private toggle = true;
}

app.html

<template>
  <require from="./item-details"></require>
  <label>
  <input type="checkbox"
    checked.bind="toggle">
    toggle
  </label>
  <div>
    <div class="au-animate"
      if.bind="toggle">
      <div repeat.for="i of 3"
        class="au-animate">
        <item-details index.bind="i"></item-details>
      </div>
    </div>
  </div>
</template>

add item-details.html file in /src/ folder

<template>
  <div element.ref="detailsEl">${index}</div>
</template>

add item-details.ts file in /src/ folder

import { bindable } from "aurelia-framework";

export class ItemDetails {

  @bindable index: number;
  detailsEl: Element;

  attached() {
    console.log('attached', this.index, this.detailsEl);
  }

  detached() {
    console.log('detached', this.index);
  }
}

au run, load page, see "toggle" checkbox, list of three items. Click "toggle" checkbox twice under one second, see output in console:

attached 0 <div element.ref=​"detailsEl" class=​"au-target" au-target-id=​"1">​0​</div>​
attached 1 <div element.ref=​"detailsEl" class=​"au-target" au-target-id=​"1">​1​</div>​
attached 2 <div element.ref=​"detailsEl" class=​"au-target" au-target-id=​"1">​2​</div>​
detached 0
detached 1
detached 2
attached 0 null
attached 1 null
attached 2 null

Expected/desired behavior:

Expected output:

attached 0 <div element.ref=​"detailsEl" class=​"au-target" au-target-id=​"1">​0​</div>​
attached 1 <div element.ref=​"detailsEl" class=​"au-target" au-target-id=​"1">​1​</div>​
attached 2 <div element.ref=​"detailsEl" class=​"au-target" au-target-id=​"1">​2​</div>​
detached 0
detached 1
detached 2
attached 0 <div element.ref=​"detailsEl" class=​"au-target" au-target-id=​"1">​0​</div>​
attached 1 <div element.ref=​"detailsEl" class=​"au-target" au-target-id=​"1">​1​</div>​
attached 2 <div element.ref=​"detailsEl" class=​"au-target" au-target-id=​"1">​2​</div>​
@Alexey1
Copy link
Contributor Author

Alexey1 commented Aug 3, 2017

The following change fixes the issue for me:

repeat.js file

  unbind() {
    this.scope = null;
    this.items = null;
    this.matcherBinding = null;
    //replace this line
    //this.viewSlot.removeAll(true);
    //with this one
    this.viewSlot.removeAll(true, true);
    this._unsubscribeCollection();
  }

As far as I can tell this causes repeater to skip leaving animations for children. Otherwise the repeater gets problematic state if it is bound again when if.bind becomes true while leaving animations are still in progress.
In the case I had, repeater DOM elements are already removed when unbind is invoked so it seems reasonable to skip animations at that point. But I can't be sure if there is no other case where it might be required, so input is needed from someone with better knowledge of the framework.

@EisenbergEffect
Copy link
Contributor

Closed by #303

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants