Skip to content
This repository has been archived by the owner on Mar 13, 2018. It is now read-only.

make template.ref assignable #54

Open
rafaelw opened this issue Apr 19, 2013 · 10 comments
Open

make template.ref assignable #54

rafaelw opened this issue Apr 19, 2013 · 10 comments

Comments

@rafaelw
Copy link
Contributor

rafaelw commented Apr 19, 2013

set ref(template) {
 if (!template instanceof HTMLTemplateElement)
  throw TypeError();

 setAttribute('ref', template.id);
 // set ref internal reference.
}
@warpech
Copy link

warpech commented Jul 9, 2013

+1 on this issue. It seems that you can change ref attribute only until a model is set. Here is a fiddle to play with:
http://jsfiddle.net/wGswV/7/

Is there a way to force rerendering of a template after ref was changed? I tried HTMLTemplateElement.bootstrap but no luck...

@rafaelw
Copy link
Contributor Author

rafaelw commented Jul 9, 2013

@warpech, I didn't intend this bug to be about allowing the ref being set to cause template to re-render with (possibly) different content.

Can you say more about your use case?

@collin
Copy link

collin commented Aug 24, 2013

@rafaelw I have a use case on this. Roughly:

<template id="app" bind ref="{{state}}"></template>

<template id="unauthorized">
  <h1> Please Log In </h1>
  <input name="Password" placeholder="enter the secret password" 
            onchange="if(this.value == 'friend') App.state = 'welcome'; else alert('Wrong Password');"
  />
</template>

<template id="welcome">
  <h1> Welcome! </h1>
  <a href="#" onclick="App.state = 'over';">Click to Win!</a>
</template>

<template id="over">
  <h1>Congratulations. You won the app!</h1>
</template>
document.app.model = window.App = { state:'unauthorized' };

You can almost do this now by combinding if and ref.

<template id="app" bind if="{{state}}" ref="{{state}}"></template>
App.state = FIRST_STATE
App.state = undefined
App.state = NEXT_STATE

That'll clear out the content when state is empty. Or at least it will if you do this one step at a time from the console or otherwise relinquish control to the system so the bindings go off.

This is a rather simplistic implementation of a router, but I think re-rendering when ref changes is an obvious win.

@collin
Copy link

collin commented Sep 17, 2013

@rafaelw I've been peeking at the source wondering if I could make bound template refs support this case but I can't really find a good place to start in the source/how to test for it.

Any tips?

@jmesserly
Copy link
Contributor

@collin -- could you accomplish the same with "bind if"? for example:

<template id="app" bind>
<template if="{{state == 'unauthorized'}}">
  <h1> Please Log In </h1>
  <input name="Password" placeholder="enter the secret password" 
            onchange="if(this.value == 'friend') App.state = 'welcome'; else alert('Wrong Password');"
  />
</template>

<template if="{{state == 'welcome'}}">
  <h1> Welcome! </h1>
  <a href="#" onclick="App.state = 'over';">Click to Win!</a>
</template>

<template if="{{state == 'unauthorized'}}">
  <h1>Congratulations. You won the app!</h1>
</template>
</template>

note, I am using http://www.polymer-project.org/docs/polymer/expressions.html for the == operator.

@collin
Copy link

collin commented Sep 18, 2013

Yes, though I suppose I'd rather do it with updating ref attributes, putting every route for an app in a big conditional in the main template seems a little bit much.

@rafaelw
Copy link
Contributor Author

rafaelw commented Sep 26, 2013

Hmmm... I'm willing to go down the route of the fully dynamic ref binding here. This would mean that anytime the value of the ref changes, all instances are destroyed and new ones are created with the new ref.

@jmesserly @sjmiles @sorvell @ajklein @arv Thoughts?

@jmesserly
Copy link
Contributor

Offhand, it sounds reasonable to me.

@collin
Copy link

collin commented Sep 26, 2013

As shown here, this is a terrible idea, you need to hook into the history api to prevent regular navigation. And there would certainly need to be some code in between the raw pathname and the ref attribute for the case of a route with dynamic segments. But this is the close to the way I'd like to architect a "single page application":

<html>
  <body>
    <header>
      <img src="logo.png" alt="A Logo" />
      <nav><!-- Some Links --></nav>
      <template bind ref="{{location.pathname}}-header" />
    </header>
    <article>
      <template bind ref="{{location.pathname}}-article" />
    </article>
    <aside>
      <template bind ref="{{location.pathname}}-aside" />
    </aside>
    <footer>
      <nav><!-- More Links --></nave>
    </footer>
  <body>
</html>
var templates = document.querySelectorAll("template[bind][ref]")
for (var i = templates.length - 1; i >= 0; i--) {
  templates[i].model = window;
};

I don't really know why I'm posting an example so similar to the one I alread did. I guess I'm just trying to say "please" :)

@jmesserly jmesserly self-assigned this Aug 7, 2014
@jmesserly
Copy link
Contributor

@rafaelw do you like this idea? if so, the impl seems really simple now that "ref" is bindable. Although not sure how to reconcile with the request in #167 ... maybe we need to split refId and refTemplate into separate properties

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

No branches or pull requests

5 participants