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

Re-render a template? #4

Open
hamishtaplin opened this issue Feb 7, 2016 · 12 comments
Open

Re-render a template? #4

hamishtaplin opened this issue Feb 7, 2016 · 12 comments
Assignees

Comments

@hamishtaplin
Copy link

Use-case

Using a listTemplate, I would like to make the relatedContent area dynamic, populating it with content when a listItemLockup is highlighted by the user.

Consider the following (simplified) page:

import ATV from 'atvjs';
import template from './template.hbs';

const APIURL = 'http://myapi/shows';

let Page = ATV.Page.create({
  name: 'shows',
  template: template,
  events: {
    select(e) {
      console.log(e);
    },
    highlight(e) {
      // RE-RENDER
    }
  },
  ready(options, resolve, reject) {
    ATV.Ajax
      .get(APIURL)
      .then((xhr) => {
        let response = xhr.response;
        resolve(response);
      }, (xhr) => {
        let response = xhr.response;
        reject({
          status: xhr.status,
          message: response.message
        });
      });
  }
});

export default Page;

Using the ReactJS model as an analogy, I would like to be able to do something like:

  • on select event, derive data from event object to create "related content".
  • manipulate the 'state' (data) of that page that gets passed to the template.
  • re-render the template with new data.

I tried to do this by storing a reference to the resolve method passed into ready and giving that fresh data but, although I can see output in the console that this has done something with the data, the page doesn't re-render.

I'm assuming this is possible somehow, I'm probably missing something really obvious...

EDIT:

Having played around, it seems you can do some old-fashioned DOM traversal/manipulation using the reference to doc that the afterReady method receives. Although this is a passable way of doing things, I would be interested to know if there scope for something more aligned with the way modern SPA's are built, rather than hunting down nodes and injecting content in to them.

@emadalam
Copy link
Owner

@hamishtaplin The whole emphasis of this framework is to provide a high level TVJS app architecture with a very thin layer on top of the existing TVJS framework and streamline any mundane tasks that we as developers may need to do while using the TVML templates alongside TVJS framework. As a result there are no models or model-to-view data bindings available in the whole framework as such. If we need to implement it, this is something that needs to be carefully thought of at the whole framework architecture level. On a side note, you may check out this project, https://github.com/ramitos/react-tvml that implements react bindings for TVML app.

Having said that, you brought a very good point of refreshing the current state of the document with the updated data, that is a feature I believe, is worth having. Something like this.refresh(data) makes a lot of sense to me, which can be called from within the event handlers of the Page objects. I can take this as a feature request and work towards implementing it.

PS: Even the latest and the greatest frameworks (like ReactJS in your example), also relies on the "old-fashioned DOM traversal/manipulation" at their core 😉

@emadalam emadalam self-assigned this Mar 28, 2016
@spunkedy
Copy link

spunkedy commented Apr 7, 2016

I solved this via something simple like:

  var getData = function(callback){
      ATV
          .Ajax
          .get(url)
          .then(function(xhr) {
              // xhr succeeded
              var response = xhr.response;
              console.log("Response");
              console.log(response);
              // call resolve with the data that will be applied to the template
              // you can even call resolve with false to skip navigation
              callback(response);
          }, function(xhr) {
              // xhr failed
              var response = xhr.response;

              console.log("Rejected");
              console.log(response);
          });
    }
    getData(function(currentResponse){
      if(!(JSON.stringify(getProp(lastData)) === JSON.stringify(getProp(currentResponse)))){
        ATV.Navigation.navigate(currentPage,ATV._.extend(currentResponse,currentOptions), true);
      }
    });

This is just a quick example of how I query the backend data system. This is until I can get websockets implemented.

The true in navigate tells it to refresh not re navigate.

@spunkedy
Copy link

spunkedy commented Apr 7, 2016

It would be nice to see some handlebar reactive data binding though.

@emadalam emadalam added this to the Milestone-Enhancements milestone Jan 1, 2017
@KevinBeckers
Copy link

Whats the status of the websockets/handlebar enhancements?

@spunkedy
Copy link

@KevinBeckers as far as I know, you cannot use web sockets still. This is a limitation from the tvOS and js client.

I got it to work doing longpolling and having a socket.js connection.

@KevinBeckers
Copy link

Can you show how you solved it?
Thank you

@spunkedy
Copy link

I don't have the code around anymore. If I get a chance later I might pop it back in here. The server side has to be able to support it.

@KevinBeckers
Copy link

That would be great!

@spunkedy
Copy link

I found some of the code. I haven't tested this in a while however, here it is.

https://gist.github.com/spunkedy/27aa9d3db6abdcb401f75c67da8be8e3

Hope this helps. I didn't include the server side that creates the channel that accepts a longpolling mechanism.

The server side is a web socket supporting longpolling which was good enough for what I was doing.

@KevinBeckers
Copy link

Thanks, I will try to get it working.
If I find anything useful I will get back.

@spunkedy
Copy link

Here is the updated gist. I was kinda driven crazy by it.
I use elixir / phoenix on the backend, and you are able to use long polling on it.

I am on phoenix 1.2 with this project example.

https://gist.github.com/spunkedy/c8f476a0c5daf417a7b17083a7ced55e

Basically you have to take care of references to location and window. So I was a little misleading, however it does work well, but if you are using something else like socket.io you will have to adapt it.

@KevinBeckers
Copy link

Super!
I don't have a phoenix project to test it on. But I will try to work it out.

It would be pretty awesome to incorporate this in the framework!
Thanks for the help.

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

No branches or pull requests

4 participants