Wednesday, 20 April 2016

Angular Js - lesson 2

/*
A Single Page Application (SPA) which the user uses to post a new link of some website with a title and other users can vote on any link to show its ratings. The number of votes determine which website should be on shown higher than other websites. There are three components which are coded in the file app.ts and their names are given below:
1. Article
2. ArticleComponent
3. RedditApp

There is one html page namely index.html which shows the list of the articles along with their voting and buttons for voting up or voting down an article. Moreover, there are two text boxes where a user can enter a new title and a new link to be added to the list of articled after the user has clicked on a button that is used for adding new article to the collection of articles.
*/

/*app.ts*/

/// <reference path="node_modules/angular2/ts/typings/node/node.d.ts"/>
/// <reference path="node_modules/angular2/typings/browser.d.ts"/>

import { bootstrap } from 'angular2/platform/browser';
import { Component } from 'angular2/core';

@Component({
    selector: 'reddit-article',
    inputs: ['article'],
    host:{
        class: 'row'
    },
    template: `
        <div class="four wide column center aligned votes">
            <div class="ui statistic">
                <div class="value">
                    {{ article.votes }}
                </div>
                <div class="label">
                    Points
                </div>
            </div>
        </div>
        <div class="twelve wide column">
            <a class="ui large header" href="{{ article.link }}">
                {{ article.title }}
            </a>
            <div class="meta">
                ({{ article.domain() }})
            </div>
            <ul class="ui big horizontal list voters">
                <li class="item">
                    <a href (click)="voteUp()">
                        <i class="arrow up icon"></i>
                        upvote
                    </a>
                </li>
                <li class="item">
                    <a href (click)="voteDown()">
                        <i class="arrow down icon"></i>
                        downvote
                    </a>
                </li>
            </ul>
        </div>
    `
})

class ArticleComponent{
    article: Article;
 
    voteUp(): boolean{
        this.article.voteUp();
        return false;
    }
 
    voteDown(): boolean{
        this.article.voteDown();
        return false;
    }
}


class Article{
    title: string;
    link: string;
    votes: number;
 
    constructor(title: string, link:string, votes?:number){
        this.title = title;
        this.link = link;
        this.votes = votes || 0;
    }  
 
    voteUp(): void {
        this.votes += 1;
    }
 
    voteDown(): void {
        this.votes -= 1;
    }
    domain(): string{
        try {
            /* split() method returns an array and we assign the element at index [1] of that array to local constant link below.*/
            const link: string = this.link.split('//')[1];
             /* split() method returns an array and we assign the element at index [0] of that array to local constant link below.*/
            return link.split('/')[0];
        } catch (err) {
            return null;
        }
    }
}

@Component({
    selector: 'reddit',
    directives: [ArticleComponent],
    template: `
        <form class="ui large form segment">
            <h3 class="ui header">Add a Link</h3>
            <div class="field">
                <label for="title">Title:</label>
                <input name="title" #newtitle>
            </div>
            <div class="field">
                <label for="link">Link:</label>
                <input name="link" #newlink>
            </div>
         
            <button (click)="addArticle(newtitle, newlink)"
                class="ui positive right floated button">
                Submit link
            </button>
</form>

<div class="ui grid posts">
    <reddit-article *ngFor="#someArticle of sortedArticles()"
                        [article]="someArticle">
    </reddit-article>
</div>
    `
})
class RedditApp{
    articles: Article[];
    /*We can write the above as below also:
    articles : Array<Article>
    This is called generics. The array will contain elements of type Article.
    */
    constructor(){
        this.articles = [
            new Article('Anuglar 2', 'http://angular.io', 10),
            new Article('Fullstack', 'http://fullstack.io', 8),
            new Article('Angular Homepage', 'http://angular.io', 6),
        ];
    }
 
    addArticle(title: HTMLInputElement, link: HTMLInputElement): void{
        console.log(`Adding article title: ${title.value} and link:${link.value}`);
        this.articles.push(new Article(title.value, link.value, 0));//0 stands for number of votes.
        //Clearing the input field values.
        title.value = '';
        link.value = '';
    }
 
    sortedArticles(): Article[]{
        return this.articles.sort(
            (a: Article, b: Article) => b.votes - a.votes
        );
    }
}

bootstrap(RedditApp);

/****************************************************************************/
/* index.html */
<!doctype html>
<html>
  <head>
    <title>Angular 2 - Simple Reddit</title>
    <link rel="icon" type="image/png" href="resources/images/favicon-32x32.png" sizes="32x32" />
    <link rel="icon" href="resources/images/favicon.ico" />
    <!-- Libraries -->
    <script src="node_modules/es6-shim/es6-shim.js"></script>
    <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/rxjs/bundles/Rx.js"></script>
    <script src="node_modules/angular2/bundles/angular2.dev.js"></script>

    <!-- Stylesheet -->
    <link rel="stylesheet" type="text/css" href="resources/vendor/semantic.min.css">
    <link rel="stylesheet" type="text/css" href="styles.css">
  </head>
  <body>

    <!-- Configure System.js, our module loader -->
    <script>
      System.config({
        packages: {      
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        }
      });
      System.import('app.js')
            .then(null, console.error.bind(console));
    </script>

    <!-- Menu Bar -->
    <div class="ui menu">
      <div class="ui container">
        <a href="#" class="header item">
          <img class="logo" src="resources/images/ng-book-2-minibook.png">
          ng-book 2
        </a>
        <div class="header item borderless">
          <h1 class="ui header">
            Angular 2 Simple Reddit
          </h1>
        </div>
      </div>
    </div>

    <div class="ui main text container">
      <reddit></reddit> <!-- <--- Our app loads here! -->
    </div>

  </body>
</html>


/****************************************************************************/
/*styles.css*/
.ui.menu .item img.logo {
    margin-right: 1.5em;
}

form.ui.segment.form {
  background-color: #F1F9FF;
  margin-top: 2em;
}

form.form:after {
  content: '';
  display: block;
  height: 0;
  clear: both;
  visibility: hidden;
}

.votes {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #E6E6E6;
  padding: 1em 0;
  border-radius: 5px;
}

.ui.grid.posts {
  margin-top: 2em;
}

.meta {
  color: #9A9A9A
}

.ui.grid>.row>.column.votes {
  display: flex;
}

ul.ui.list li:before {
  content: '';
}

/****************************************************************************/
/*tsconfig.json*/
{
  "compilerOptions": {
    "target": "ES5",
    "module": "system",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  },
  "files": [
    "app.ts",
    "node_modules/angular2/ts/typings/node/node.d.ts",
    "node_modules/angular2/typings/browser.d.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}
/****************************************************************************/

No comments:

Post a Comment