Question

I've been playing with ractive.js and am trying to get a sense of what it is capable of. I have an example that is fairly common, a view with some internal state logic that I'd like to cleanly keep track of. After going through the tutorials this seems like something Ractive would be really good at, but I'm having a hard time figuring this out.


Update: I've revised my test case below based on feedback in the first answer I got, to clarify the exact problem I've been having. You can see the complete example here: http://jsfiddle.net/e7Mjm/1/

First, I have a ractive template:

<div id="toc-view"></div>
<script id="ractive-toc" type="text/ractive">
  <ul>
  {{#chapters}}
    <li class="{{type}}">
      <span class="ordinal">{{ordinalize(ordinal)}}</span>
      <a data-id="{{element_id}}">{{title}}</a>
      {{#(sections.length > 0)}}
        <a class="{{open ? 'expand open' : 'expand'}}" on-click="toggleSections"></a>
        {{#open}}
        <ul class="{{open ? 'sections open' : 'sections'}}">
          {{#sections}}{{>section}}{{/sections}}
        </ul>
        {{/open}}
      {{/()}}
    </li>
  {{/chapters}}
  </ul>

  <!-- {{>section}} -->
  <li class="{{type}}">
    <span class="ordinal">{{ordinalize(ordinal)}}</span>
    <a data-id="{{element_id}}">{{title}}</a>
  </li>
  <!-- {{/section}} -->
</script>

I have some simple CSS styles to format this:

ul { list-style: none; padding: 0; margin: 0}
ul.sections { padding-left: 20px; }
a.expand { color: red; }
a.expand:before { content: "+"; }
a.expand.open { color: blue; }
a.expand.open:before { content: "-"; }

And the following Javascript to make it all work:

data = [
  {
    id: "smith-about",
    title: "About this book",
    type: "front-matter"
  },
  {
    id: "smith-preface",
    title: "Preface",
    type: "front-matter"
  },
  {
    id: "smith-ch01",
    title: "Intro to Biology",
    ordinal: "1",
    type: "chapter",
    sections: [
      {
        id: "smith-ch01-s01",
        title: "What is biology?",
        ordinal: "1.1",
        type: "section"
      },
      {
        id: "smith-ch01-s02",
        title: "What is a biologist?",
        ordinal: "1.2",
        type: "section"
      },
      {
        id: "smith-ch01-s03",
        title: "So you want to be a biologist?",
        ordinal: "1.3",
        type: "section"
      }
    ]
  },
  {
    id: "smith-ch02",
    title: "Applied Biology",
    ordinal: "2",
    type: "chapter",
    sections: [
      {
        id: "smith-ch02-s01",
        title: "Biology in the lab",
        ordinal: "2.1",
        type: "section"
      },
      {
        id: "smith-ch02-s02",
        title: "Biology in the field",
        ordinal: "2.2",
        type: "section"
      },
      {
        id: "smith-ch02-s03",
        title: "Biology in the classroom",
        ordinal: "2.3",
        type: "section"
      }
    ]
  }
]

ractive = new Ractive({
  el: 'toc-view',
  template: '#ractive-toc',
  data: {
    chapters: data,
    ordinalize: function(ordinal) {
      return ordinal ? ordinal + "." : "▸";
    }
  }
});

ractive.on('toggleSections', function(event) {
    event.context.open = !event.context.open;
    this.update();
});

If you try out the JS Fiddle you'll see the template renders correctly but the interaction behavior isn't quite right: If you click on a.expand it does open that section, but it also changes the class of all the other a.expand icons, not just the one that was clicked.

This is the real issue I've been having, in the ractive event binding there doesn't seem to be a very good way for me to define an interaction that affects only the particular data object the user is interacting with, instead the interaction seems to affect all the data.

Any insight into how to scope this correctly?

Was it helpful?

Solution

Here is a example http://jsfiddle.net/e7Mjm/

I changed to

{{#open}}{{#sections}}{{>section}}{{/sections}}{{/open}}

Now it will render "on demand" when you open

and you can use event.context. Just do

event.context.open = !event.context.open;
this.update();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top