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

Long dynamic path for sub-templates and/or sub-components #124

Closed
benouat opened this issue Apr 8, 2014 · 1 comment
Closed

Long dynamic path for sub-templates and/or sub-components #124

benouat opened this issue Apr 8, 2014 · 1 comment
Labels

Comments

@benouat
Copy link
Member

benouat commented Apr 8, 2014

I was lately trying to implement a Tabbar component such as this one

<#tabbar selected="{selected}">
  <@tab label="Tab1">This is tab 1</@tab>
  <@tab label="Tab2">This is tab 2</@tab>
  <@tab label="Tab3">This is tab 3</@tab>
</#tabbar>

Consider the following source code

var Class = require("hsp/klass");

var TabCtrl = Class({
  attributes: {
    onselect: { type: "callback" },
    label: { type: "template" },
    body: { type: "template", defaultContent: true }
  },
  $init: function(parent) {
    this.parent = parent;
    this.selected = false;
  },

  onSelectedChange: function() {
    this.onselect && this.onselect(this.parent.selected);
  }
});

var TabBarCtrl = Class({
  attributes: {
    "class": { type: "string" },
    selected: { type: "int", defaultValue: 0, binding: "2-way" }
  },
  elements: {
    "tab": { type: "component", controller: TabCtrl }
  },
  $init: function() {
    this.selected = 0; //TODO remove when defaultValue is really implemented
    this.updateSelectedBody(null, this.selected);
  },

  onSelectedcontentChange: function() {
    console.log("selectedcontent changed");
  },

  updateSelectedBody: function(previous, next) {
    if (previous) {
      this.content[previous].selected = false;
    }
    this.selectedcontent = this.content && this.content[next];
    this.selectedcontent.selected = true;

    this.selected = next;
  },

  onselect: function(event) {
    var target = event.target,
        previous = this.selected,
        next;

    event.preventDefault();

    while(target.tagName.toLowerCase() !== "a") {
      target = target.parentNode;
    }
    next = parseInt(target.dataset.index, 10);
    if (next === previous) { return; }
    this.updateSelectedBody(previous, next);
  }
});

#template tabbar using ctrl:TabBarCtrl
  <div class="x-tabbar {ctrl.class}">
    <nav class="x-tabs" onclick="{ctrl.onselect(event)}">
    {foreach idx, tab in ctrl.content}
      <a class="{'selected': ctrl.selected === idx}" data-index="{idx}"><#tab.label /></a>
    {/foreach}
    </nav>
    <div class="x-tab-content">
        <#ctrl.selectedcontent.body />
    </div>
  </div>
#/template

module.exports = tabbar;

It appears that when the property ctrl.selectedcontent is updated, the corresponding onSelectedcontentChange() is called, but the child component inclusion is apparently not refreshed, which is not the awaited behavior

PS: ideally I would even have written that in the first place
<#ctrl.content[ctrl.selected].body /> and be waiting for the same refresh to occurs but unfortunately it is not supported as well for now...

@benouat benouat added the bug label Apr 9, 2014
@divdavem
Copy link
Member

@b-laporte I had a look to lines 554-611 in $root.js, and I am wondering: isn't this duplicating code? Isn't a template path an expression? Couldn't it be observed by the expression handler, just like expressions in text nodes and others?

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

Successfully merging a pull request may close this issue.

2 participants