Giter VIP home page Giter VIP logo

my-angular2-quickstart's Introduction

my-angular2-quickstart

This is a repo that was my first attempt of Angular2. I used Angular2 QuickStart as my seed project.

This repo contains all my curiosities of Angular2 with my study notes that I found that it is interesting to record.

##Notes ###1. How does import work in Angular 2? Relative path and absolute path for import different files, components.

###2. Instance Angular 2 Component Two times Bootstrap angular 2 compoents, different with bootstrap components and non-bootstrap components. Cannot use single bootstrap component twice on the same page. Non-main components can be created as much as you want.

###3. How to create an empty object based on interface file in component Case produce:
I need to create a form filled in with empty object attributes. I got object.attribute is undefined error. What I did before is:

   // dj is an interface.
   public newDj : dj;

And for the HTML, I used ngModel for two-way bindings:

<div class="form-group">
	<label for="name">Name</label>
	<input type="text" class="form-control" required 
	   	[(ngModel)] = "newDj.name" />
</div>

The reason for this is becasue public newDj : dj; just declared an object called newDj and type of newDj is dj. It didn't create an instance of dj. After read the post: How can I create an object based on an interface file definition in TypeScript?, with this gentle man's solution. I did:

public newDj = <dj>{};

Boom, fixed the problem!

###4. How to pass and access input properties in a component class? Case produce:
I learned how to pass properties from Angular 2 tutorial. It uses square brackets for binding and declares inputs: [...]. I can access the input properties in the component template without errors. However, I had a property ... is undefined. if I try to display the property in a component class.
Parent template:

<dj-form *ngIf="openNewForm" [rankvalue]="currentRank"></dj-form>

Child Component code:

@Component({
	selector: 'dj-form',
	templateUrl: 'app/dj-form/dj-form.component.html',
	inputs: ['rankvalue']
})
export class DjFormComponent {
	public newDj = <dj> {};

	createDj() {
		consolo.log(rankvalue);
		consolo.log(this.rankvalue);
	}
}

Obviously, I don't have any access or any variable called rankvalue. But what does inputs in the component annotation do?
I can get this value by injecting service to watch this variable. But I don't want to do that. Is it any other way that I can access the property in a component class? After read this article, I got a solution. And I favor the solution that Tom Buyse showed in his blog. I changed child component code:

@Component({
	selector: 'dj-form',
	templateUrl: 'app/dj-form/dj-form.component.html',
})

export class DjFormComponent {
	@Input() rankvalue;

	createDj() {
		consolo.log(this.rankvalue);
	}
}

No more non sense inputs array in component. I like this solution because it clearly shows the scope of input properties and also it looks like Angular 1 for people like me did a lot angular 1 projects. @input() rankvalue' is similar to $scope.rankvalue for binding value to directive in angular 1. Tom Buyse also mentioned that we are not able to access the input properites before the view is rendering.

###5. Is selector attribute necessary for Component? Selector is not necessary. I discovered this after I implemented routing in the app. It's no harm to have one in the component anyway.

###6. How to apply different html classes based on dynamic value? I have ngFor for looping through an array of objects. Each object has multiple attributes. I want to apply different materializecss grid class based on object's ranking (one of the attribute of the object). Here is what I want.

Dashboard

Here is what I do using ngClass in Angular 2.

<div class="col s12" *ngFor="#dj of Djs" [ngClass]="{l6: dj.rank === 1, l3: dj.rank < 6, l2: dj.rank >= 6}">
</div>

Because I need to evaluate 3 different expressions, I use ngClass for apply different style class. I could use the syntax like [class.l6]="dj.rank===1", works in Angular 2. However, the limitation is I can't do multiple evaluation at a time. I have to write a lot [class....]="..." to make this happen.

###7. How to make one to many relationship in Typescript? I am at the stage that I want to develop a one-to-many relation for Dj object. It makes sense that each Dj has a lot of songs, but how can I implement in Typescript?

One-To-Many

Define a Song class and import to Dj interface:

import {Song} from './song'
export interface Dj {
	id: number;
	name: string;
	rank: number;
	imageUrl?: string;
	songs?: Song[];
}

Notice that: the question mark ? indicated that the attribute is optional, another words, is not required. I feel like I should define Dj to Class instead of interface because now I need some logic for Dj class and I can have some setter and getter function, particular useful for setting and getting songs. But for now, I will just leave it as interface, cause it does its job.

###8. How to filter an array based on some value in TypeScript way? Recall from Question 7, I have a one-to-many relationship in my application: one Dj has many songs. Now I encouter a problem that if I receive 100 random songs from the backend, how can I quickly identify which song belongs to which Dj? An Easy way to implment this is to let backend handle it by passing the dj_id through API and writes an query to get all the songs belong to this dj_id. What if I don't have the luxury, I have to handle it in the front-end side? (Yeah, I know, the backend guy is too lazy.) Luckily, I can use arr.filter() method which is a standard function in ES5. I wasn't so sure how to use arr.filter() in TypeScript; however, John Papa shows a good example in his repo.

getHero(id: number) {
	return Promise.resolve(HEROES).then(
		heroes => heroes.filter(h => h.id === id)[0]
	);
}

Basically, it is saying get me all h(hero) that saticified its id is equivalent to the id passing from the parameter. Excatly what I want: give me all the songs that belong to this Dj.

My implmentation:

getSongsByDjId(dj_id: number) {
	return Promise.resolve(songs).then(
		songs => songs.filter(song => song.dj_id === dj_id)
	)
}

A question might rise: Where does this song come from?
song is a temporary variable that reference an element of songs. I can name it whatever I want.

###9. What changes do I need to do to my SystemJS config blocks to tell it to look in dist/ for the compiled JS files? I believe a lot of people like me who is very new to SystemJS and TypeScript don't like the .js and .js.map complie right beside .ts. I would like to separate src files and complie files. But, how to do that and also tell SystemJS to look into that?
First, need to add outDir attribute in tsconfig.json file. outDir allows you to redirect output structure to the directory.

{
  "compilerOptions": {
    "target": "ES5",
    "module": "system",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false,
    "outDir": "dist"
  },
  "exclude": [
    "node_modules"
  ]
}

And then, I need to tell SystemJS to look in the dist folder, because I ask to put all the complier .js and .js.map code to my dist/ folder.

System.config({
	map: { app: 'dist'},
    packages: {        
      app: {
        format: 'register',
        defaultExtension: 'js'
      }
    }
  });
  System.import('app/boot')
        .then(null, console.error.bind(console));

According to Rob Wormald, I need to add map: { app: 'dist' } in the System.config(). Very nice, now the structure of the application is much nicer and I can just git ignore the src folder.

my-angular2-quickstart's People

Contributors

shaohaolin avatar

Stargazers

Damian Bielecki avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.