Binding Data to Lists

edited May 2016 in Enyo 2.7
Hi! I am writing in order to ask for some help about data lists. I have started developing Enyo APPs for a ocuple of weeks and I am still a rookie. At the moment I am dealing with lists and I am a bit stuck.

I have designed a layout for lists that worked at first, but when moving it to a new class defined by me I dont manage to make list items appear. What is more, the data list element does not get all the elements from the collection, but only two of them.

The code is here:
var
kind = require('enyo/kind'),
Img = require('enyo/Image'),
GridList = require('moonstone/DataList'),
FittableColumns = require('layout/FittableColumns'),
BodyText = require('moonstone/BodyText'),
GridListItem = require('moonstone/Item'),
IconButton = require('moonstone/IconButton'),
Collection = require('enyo/Collection');

var ChannelListItem = kind({
kind: FittableColumns,
classes: 'channelListItem',
components: [
.........
]
});

var ChannelList = kind({
kind: GridList,
fit:true,
classes: 'channelList',
components:[
{ kind:GridListItem,
components:[
{kind: ChannelListItem, name:'ChannelListItem'}
],

bindings: [
{from: '.model.programTitle', to: '.$.ChannelListItem.$.ProgramTitle.content'},
{from: '.model.channelTitle', to: '.$.ChannelListItem.$.ChannelTitle.content'},
{from: '.model.thumbnail', to: '.$.ChannelListItem.$.ChannelLogo.src'},
{from: '.model.channelNumber',to: '.$.ChannelListItem.$.ChannelNumber.content'}
],

create: function () {
this.inherited(arguments);
console.log(this);
}
}
],

bindings: [
{from: '.channels', to: '.collection'}
],

create: function () {
this.inherited(arguments);

this.set('channels', new Collection([
{programTitle:'Game Of Thrones 1',channelTitle:'HBO',channelNumber:'1',thumbnail:'../../../assets/channelLogo.png'},
{programTitle:'Game Of Thrones 2',channelTitle:'HBO',channelNumber:'1',thumbnail:'../../../assets/channelLogo.png'},
{programTitle:'Game Of Thrones 3',channelTitle:'HBO',channelNumber:'1',thumbnail:'../../../assets/channelLogo.png'}
]));
}
});
module.exports = kind({ kind: FittableColumns, name: 'ChannelLists', components: [ {kind: ChannelList, name:'AllChannelsList'} ] });
Can you help me to determine what am I doing wrong with the data list? That's all, thank you so much for yout time.

Comments

  • The issue is in override create on the instances of GridListItem and calling this.inherited. You should only add methods in kinds (configs passed to kind()) rather than instances (configs within a components block). In this case, trying to call this.inherited fails because that's a special method to walk up the prototype hierarchy but only works in the context of a new kind.

    Removing the create method with the console.log should get you going again!
  • As a quick followup, there are a few anti-patterns in the code:

    1. Don't bind deeply ($.something.$.someotherthing)
    2. Don't start bindings with . in Enyo 2.7. This slows things down.
    3. FittableColumns may not be needed (you didn't show the component block). You might want to derive ChannelListItem directly from GridListItem and skip the indirection.
    4. You can move the bindings directly into your ChannelListItem (if you derive it from the GridListItem), then you don't have the bindings cluttering up your GridList.
  • edited June 2016
    Thank you so much for your fast answer and your code guidelines, it is my second week working on it and the documentation is not as clear as other frameworks, so it is hard for me to learn, but the framework is simply awesome, never imagined developing APPs for TVs was so easy.

    At the end the problem was other (the container for the lists had a small height and was hidding the items, no problem with overriding the constructor). The guidelines has been really useful, but only in the point of not using fittable columns, for what I see to have elementes aligned in divs it is the best option (not sure which impact it has in efficiency).

    Here I post my solution:
    
    var
      kind =            require('enyo/kind'),
      Img =             require('enyo/Image'),
      GridList =        require('moonstone/DataList'),
      FittableColumns = require('layout/FittableColumns'),
      BodyText =        require('moonstone/BodyText'),
      GridListItem =    require('moonstone/Item'),
      IconButton =      require('moonstone/IconButton'),
      Collection =      require('enyo/Collection');
    
    var ChannelListItem = kind({
      kind: GridListItem,
      classes: 'channelListItemContainer',
      components: [
        { kind: FittableColumns,
          classes: 'channelListItem',
          components:[
            {name: 'ChannelLogo', classes:'channelLogo', kind:Img},
            {name: 'FavoriteImg', classes:'favoriteLogo', kind:Img, src: '../../../assets/png/favorite.png'},
            {name: 'ProgramTitle', classes:'programTitle', kind: BodyText},
            {name: 'Space', fit:true},
            {name: 'ChannelTitle', classes:'channelTitle', kind: BodyText},
            {name: 'ChannelNumber', classes:'channelNumber', kind: BodyText}
         ]}
      ],
    
      bindings:[
        {from: 'model.programTitle', to: '$.ProgramTitle.content'},
        {from: 'model.channelTitle', to: '$.ChannelTitle.content'},
        {from: 'model.thumbnail', to: '$.ChannelLogo.src'},
        {from: 'model.channelNumber',to: '$.ChannelNumber.content'}
      ],
    
    });
    
    var ChannelList = kind({
      kind: GridList,
      fit:true,
      classes: 'channelList',
      components:[
        {kind:ChannelListItem}
      ],
    
      bindings: [
        {from: 'channels', to: 'collection'}
      ],
    
      create: function () {
       this.inherited(arguments);
    
       this.set('channels', new Collection([
         {programTitle:'Game Of Thrones 1',channelTitle:'HBO',channelNumber:'1',thumbnail:'../../../assets/channelLogo.png'},
         {programTitle:'Game Of Thrones 2',channelTitle:'HBO',channelNumber:'1',thumbnail:'../../../assets/channelLogo.png'},
         {programTitle:'Game Of Thrones 3',channelTitle:'HBO',channelNumber:'1',thumbnail:'../../../assets/channelLogo.png'}
       ]));
      }
    });
    
    module.exports = kind({
      kind: FittableColumns,
      name: 'ChannelLists',
      style:'height:100%',
      components: [
        {kind: ChannelList, name:'AllChannelsList'}
      ]
    });
    
    Thank you so much for your help again. Will keep working on learning more about Enyo!
  • Glad to hear you're enjoying Enyo so far and that you got your code working. I would love to hear your feedback on how the documentation could have been more helpful. (hint: pull requests are always welcomed!)

    One last tip: As a convention, we use uppercase names for kind names (ChannelListItem ) and use lowercase names for instances. In this case, ChannelLogo, FavoriteImg, etc. would all be lowercase because they refer to instances of a component.
Sign In or Register to comment.