ViggyNash
ViggyNash

Reputation: 611

Polymer, how to use app-location?

I'm trying to use app-location in order to dynamically load articles with links to other articles and be able to use browser navigation to go back and forth between them, like you would on a normal website. My understanding of app-location is that it grabs the URL send to the browser from a link and updates its route value, allowing you to perform routing client-side. This is my first test "article", which loads fine:

<h1>Title header</h1>

<p>Here's a bunch of words and this one's <b>special</b></p>

<a id="content-link" href="/articles/test2.txt" on-tap="handleTap">link to another article</a>

test2.txt just has a p tag with some text in it.

This is what it looks like on initial load

That's what it looks like on initial load. That link on the bottom of the main section is the link I am talking about. My intent is that if I click that link, it will change the url, then app-location will grab that and change its route property, then my observer can clear the old "article", load the new one and insert it into the content area. So, because the a "new page" was loaded, I should be able to hit the browser back button to return to the above page.

However, when I click the link, it just loads the file as a raw text file and displays that: <p>A NEW PAGE GOT LOADED WOOOOOO</p>, p tags included. Obviously, I've misunderstood something, which is likely since I'm still very new to Polymer and this was meant to be a learning project. Can anyone find what I've done wrong here, or give me pointers on what I should do differently to get my idea working?

Here's my full element code:

<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html">
<link rel="import" href="../../bower_components/iron-pages/iron-pages.html">
<link rel="import" href="../../bower_components/app-route/app-*">

<dom-module id="AR_Website-app">
  <template>
    <style>
      /*header*/
      header {
        display: block;
        padding: 20px 0;
        padding-left: 30px;
        background-color: rgb(220, 60, 50);
      }

      p {
        margin: 0;
        font-family: Verdana, Geneva, sans-serif;
        font-size: 30px;
        animation: title-fadein 1s;
        animation-fill-mode: forwards;
      }

      @keyframes title-fadein {
        from {
          text-shadow: none;
          opacity:0;
        }

        to{
          text-shadow: 0 0 2px black;
          opacity:1;
        }
      }

      /*content*/
      table {
        border-collapse: collapse;
        width: 100%;
        min-height: calc(100vw - 110px);
      }

      table td {
        vertical-align: top;
        padding: 0;
      }

      table td:nth-child(1) {
        background-color: blue;
      }

      table td:nth-child(2) {
        background-color: green;
        padding: 10px;
      }

      table td:nth-child(3) {
        background-color: red;
      }
    </style>

    <app-location route="{{route}}"></app-location>
    <app-route 
      route="{{route}}" 
      pattern="/:articles" 
      data="{{routeData}}" 
      tail="{{subroute}}">
    </app-route>

    <iron-ajax url="{{route}}" handle-as="text" on-response="handleRequest"></iron-ajax>

    <header><p>The Title</p></header>
    <table>
      <tr>
        <td width="10%"><div id="left-banner">

        </div></td>
        <td width="80%">
          <div id="content">

          </div>
        </td>
        <td width="10%"><div id="right-banner">

        </div></td>
      </tr>
    </table>
  </template>

  <script>

    Polymer({

      is: 'AR_Website-app',


      observers: [
        '_routeChanged(route)'
      ],

      attached: function (){
        this.route = "/articles/test.txt"
        //console.log("Page loaded, sending request for route "+this.route)
        this.$$('iron-ajax').generateRequest();
      },

      _routeChanged: function(route) {
        console.log("new route "+route+", sending request")
        this.$$('iron-ajax').generateRequest();
      },

      handleRequest: function(event) {
        //Remove existing html snippet
        console.log("handling request")
        while (this.$$('#content *') != null){
          this.$$('#content').removeChild(this.$$('#content *'))
        }
        //Create new html code from received text
        console.log(event.detail.response)
        var div = document.createElement('div')
        div.innerHTML = event.detail.response
        for (x = 0; x < div.childNodes.length; x++){
          var content = div.childNodes[x]
          this.$$('#content').appendChild(content)
        }
        //Add event handlers for links
        //this.listen(this.$$('#content-link'), 'tap', 'handleTap')
      },

      handleTap: function(event) {
        //Cancel page load from link
        //event.preventDefault();
        //Request new html snippet
        console.log("Loading "+this.$$('#content-link').href)
        //this.set('route', this.$$('#content-link').href)
        this.route = this.$$('#content-link').href
        //this.$$('iron-ajax').generateRequest();
      }
    });
  </script>
</dom-module>

Upvotes: 2

Views: 2047

Answers (1)

User 28
User 28

Reputation: 5158

Based on your code

App directory

app
- bower_components
- articles
-- a.txt
-- b.txt
- index.html
- my-app.html

index.html

<!doctype html>
<html>
  <head>

    <link rel='import' href='my-app.html'>

  </head>
  <body>

    <my-app></my-app>

  </body>
</html>

my-app.html

<link rel='import' href='bower_components/polymer/polymer.html'>
<link rel='import' href='bower_components/app-route/app-location.html'>
<link rel='import' href='bower_components/app-route/app-route.html'>
<link rel='import' href='bower_components/iron-ajax/iron-ajax.html'>

<dom-module id='my-app'>
  <template>

    <style>
      header{display:block;padding:20px 0 20px 30px;background-color:#dc3c32}p{margin:0;font-family:Verdana,Geneva,sans-serif;font-size:30px;animation:title-fadein 1s;animation-fill-mode:forwards}@keyframes title-fadein{from{text-shadow:none;opacity:0}to{text-shadow:0 0 2px #000;opacity:1}}table{border-collapse:collapse;width:100%;min-height:calc(100vw - 110px)}table td{vertical-align:top;padding:0}table td:nth-child(1){background-color:#00f}table td:nth-child(2){background-color:green;padding:10px}table td:nth-child(3){background-color:red}
    </style>

    <app-location route='{{route}}'></app-location>
    <app-route
      route='{{route}}'
      pattern='/articles/:article'
      data='{{routeData}}'>
    </app-route>
    <iron-ajax url='/articles/[[routeData.article]]' handle-as='text' on-response='handleRequest'></iron-ajax>

    <header>
      <p>The Title</p>
    </header>
    <table>
      <tr>
        <td width='10%'><div id='left-banner'></div></td>
        <td width='80%'>
          <div id='content'>
            <div>[[article]]</div>
            <a href='/articles/a.txt'>a article</a>
            <a href='/articles/b.txt'>b article</a>
          </div>
        </td>
        <td width='10%'><div id='right-banner'></div></td>
      </tr>
    </table>

  </template>
  <script>

    Polymer({
      is: 'my-app',

      observers: [
        'routeChanged(route)'
      ],

      routeChanged: function (route) {
        if (this.$$('app-route').active)
          this.$$('iron-ajax').generateRequest();
      },

      handleRequest: function (event) {
        this.article = event.detail.response;
      }
    });

  </script>
</dom-module>

It start from app-location grab the url, update route, and that will trigger app-route, app-route try to match that url with pattern and set result to routeData, url on iron-ajax will change accordingly.

When you click on a href, url will change without reload because when iron-location active it will intercept clicks on links within your site ( see in links section and app-location use iron-location) so you don't need to anything with a href. After that routeChanged will be triggered and generate the request.

Beside, I saw you use

this.route = 'some path';

I think it should be

this.set('route.path', 'some path');

I hope this will help.

Upvotes: 4

Related Questions