`Type` in a component’s VM doesn’t work correctly with lists #2250

Closed
chasenlehara opened this Issue Feb 10, 2016 · 2 comments

Comments

Projects
None yet
3 participants
@chasenlehara
Member

chasenlehara commented Feb 10, 2016

If a can.Component has a define property that’s Type is a can.List, and that can.List has a Map type, and that can.Map has define properties, then those properties should be available on instances of the items within the list. For example:

var Item = can.Map.extend({
  define: {
    prop: {
      get: function() {
        return 'define prop';
      }
    }
  }
});

var Collection = can.List.extend({
  Map: Item
}, {});

var collectionInstance = new Collection([{}]);
collectionInstance[0].attr('prop');// Returns “define prop”

var homeTemplate = can.view.stache('<p>{{vmProp}}</p>');

can.Component.extend({
  tag: "home-page",
  template: homeTemplate,
  viewModel: {
    define: {
      collection: {
        Type: Collection
      },
      vmProp: {
        get: function() {
          var collection = this.attr('collection');
          return collection[0].attr('prop') || 'no prop';
        }
      }
    }
  }
});

var appTemplate = can.view.stache('<home-page collection="{collection}" />');

$("body").html(
  appTemplate({
    collection: [{objectProp:'object prop'}]
  })
);

// Body should have “define prop” but instead has “no prop”

Works in 2.2.9 (“define prop” is output): http://jsbin.com/cocarikefo/1/edit?html,js,output

Doesn’t work with latest (“no prop” is output): http://jsbin.com/rufavacera/1/edit?html,js,output

@daffl daffl added this to the 2.3.16 milestone Feb 13, 2016

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Feb 13, 2016

Contributor

@chasenlehara is a component necessary? Does it work if you simply .attr("collection", [{objectProp:'object prop'}] )

Contributor

justinbmeyer commented Feb 13, 2016

@chasenlehara is a component necessary? Does it work if you simply .attr("collection", [{objectProp:'object prop'}] )

@chasenlehara

This comment has been minimized.

Show comment
Hide comment
@chasenlehara

chasenlehara Feb 13, 2016

Member

Yeah, unfortunately the most simple case works, but it fails when a component is involved.

Member

chasenlehara commented Feb 13, 2016

Yeah, unfortunately the most simple case works, but it fails when a component is involved.

@daffl daffl modified the milestones: 2.3.17, 2.3.16, 2.3.18 Feb 17, 2016

@chasenlehara chasenlehara self-assigned this Feb 21, 2016

chasenlehara added a commit that referenced this issue Feb 21, 2016

chasenlehara added a commit that referenced this issue Feb 22, 2016

Don’t include %root in a component’s initial viewModel data
When a component is set up, `%root` was added to the initial `viewModel` data so it would be available in every scope. However, [`can.view.Scope` already has a special case for %root](https://github.com/canjs/canjs/blob/cee94ae7744ea6376e1f4bd7f6088b325db06555/view/scope/scope.js#L91-L94), so it’s not necessary for `can.Component` to do that.

Fixes #2250

chasenlehara added a commit that referenced this issue Feb 23, 2016

Wait to add %root to a component’s viewModel data until all of the ot…
…her attributes have been bound

When a component is set up, `%root` is added to the initial `viewModel` data so it’s available in every scope. However, this causes issues when the `%root` bindings are set up before all of the other properties, so this moves the setup for `%root` until after all the other properties have been bound.

Fixes #2250

@justinbmeyer justinbmeyer closed this in #2282 Mar 1, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment