├── README.md ├── images ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png └── 6.png └── lang └── README.tr.md /README.md: -------------------------------------------------------------------------------- 1 | Angular 4 - Notes 2 | ==================== 3 | 4 | 5 | This repository is notes of my angular 4 journey. I couldn't switched to ng2. Now I decided to give a shot and getting course about ng4. I will write everthing that I learn, Maybe this repository guide you too. 6 | 7 | Thanks [Maximilian Schwarzmuller](https://www.udemy.com/the-complete-guide-to-angular-2) for great guide. 8 | 9 | Farewell my friend. 10 | 11 | Other Languages 12 | ---------------- 13 | 14 | - [Yazıyı türkçe okumak için tıklayın](lang/README.tr.md) 15 | 16 | 17 | Index 18 | ---------------- 19 | 20 | - [Installation](#installation) 21 | - [Creating project](#creating-project) 22 | - [Serving project](#serving-project) 23 | - [Investigating created project](#investigating-created-project) 24 | - [Creating a new component](#creating-a-new-component) 25 | - [Create component with cli](#create-component-with-cli) 26 | - [Including bootstrap css to project](#including-bootstrap-css-to-project) 27 | - [Databinding](#databinding) 28 | - [Directives](#directives) 29 | - [ngIf](#ngif) 30 | - [ngFor](#ngfor) 31 | - [ngStyle](#ngstyle) 32 | - [ngClass](#ngclass) 33 | - [ngSwitch](#ngswitch) 34 | - [Input](#input) 35 | - [Output](#output) 36 | - [View Encapsulation](#view-encapsulation) 37 | - [Local Reference](#local-reference) 38 | - [ng-content](#ng-content) 39 | - [Life cycle of components](#life-cycle-of-components) 40 | - [Creating a new directive](#creating-a-new-directive) 41 | - [HostListener](#hostlistener) 42 | - [HostBinding](#hostbinding) 43 | - [Services and dependency injection](#services-and-dependency-injection) 44 | - [Injecting a service into another service](#injecting-a-service-into-another-service) 45 | - [Event emitting service](#event-emitting-service) 46 | - [Router](#router) 47 | - [Links](#links) 48 | - [Active route](#active-route) 49 | - [Navigating from code](#navigating-from-code) 50 | - [Parameters of routes](#parameters-of-routes) 51 | - [Nested routes](#nested-routes) 52 | - [Redirecting](#redirecting) 53 | 54 | ### Installation 55 | 56 | To develop some applications we need to install node.js first. If you didn't know node.js, please check it before ng4. We will use angular cli. Angular cli will help us creating stuff. Its very useful tool. 57 | 58 | ``` 59 | npm i @angular/cli -g 60 | ``` 61 | 62 | We should install `@angular/cli` with global parameter. This parameter will use global node_modules folder rather than local one. 63 | 64 | Now we can use `ng` command in terminal. 65 | 66 | 67 | ### Creating project 68 | 69 | To create project we will use `ng` command. Try to type `ng` in terminal if you get error then you failed `Installation` step. Please go there and make sure you did this steps right. 70 | 71 | ng command has some more arguments too. We will come to that but rightnow we just have to create a project so we should use `new` argument. 72 | 73 | This argument will create a new project structure in current working directory. But we should give some project name to proceed. I will name the project as "my-first-app" 74 | 75 | ``` 76 | ng new my-first-app 77 | ``` 78 | 79 | After using this command in terminal some files will generated by `ng`. It will install necessary packages via npm. Wait until installation is done. 80 | 81 | 82 | ### Serving project 83 | 84 | We just create a new project. Proceed to `my-first-app` folder. Use `serve` command of `ng`. It will do packaging stuff and create a http server. 85 | 86 | ``` 87 | cd my-first-app 88 | ng serve 89 | ``` 90 | 91 | In terminal output, there should be a url address. If you can't figure the address then with `--port xxx` parameter, you can change port number to whatever you want. 92 | 93 | ``` 94 | ng serve --port 8080 95 | ``` 96 | 97 | Typescript compiled and Webpack packed your application. 98 | 99 | Now try to access to [http://localhost:8080](http://localhost:8080) 100 | 101 | 102 | ### Investigating created project 103 | 104 | > Before going deeper make sure you opened the project with an IDE software. I recommend Visual Studio Code or WebStorm.. 105 | 106 | In project folder we can see `e2e` folder, `src` folder, and some files. `e2e` folder contains end to end testing stuff. We will check it after. All our project source stuff are in `src` folder. Other files contains information about configurations, required packages etc. We will check them when we need. 107 | 108 | Inside of `src` folder there are multiple files. The most important file in this folder is `index.html` file. This file is the highest point of our project. If you open it you will see something like this. 109 | 110 | ```html 111 | 112 | 113 | 114 | 115 | MyFirstApp 116 | 117 | 118 | 119 | 120 | Loading... 121 | 122 | 123 | ``` 124 | 125 | In side of body element we have special tag which aren't in html standard. Its `app-root` element. 126 | 127 | If you check `app` folder. Go dive into `app.component.ts` file. 128 | 129 | ```ts 130 | import { Component } from '@angular/core'; 131 | 132 | @Component({ 133 | selector: 'app-root', 134 | templateUrl: './app.component.html', 135 | styleUrls: ['./app.component.css'] 136 | }) 137 | export class AppComponent { 138 | } 139 | ``` 140 | 141 | As you can see there is some property `selector` is setted to `app-root`. In angular components will bind to element that given as `selector`. Selector is kinda like css element selector. If you use `name` then you will select `tag`, if you use `.name` then you will select `class`, if you use `[name]` you will select `property`. 142 | 143 | `templateUrl` property routes component's template location. You can use `template` property too if you don't want to create html file. 144 | 145 | ```ts 146 | import { Component } from '@angular/core'; 147 | 148 | @Component({ 149 | selector: 'app-root', 150 | template: ` 151 | hi 152 | `, 153 | styleUrls: ['./app.component.css'] 154 | }) 155 | export class AppComponent { 156 | } 157 | ``` 158 | 159 | `styleUrls` property shows us component's css file location. You can use `styles` too if you don't want to create css file. Difference between `template` and `styles`, styles is expecting an array of string, not directly string. 160 | 161 | ```ts 162 | import { Component } from '@angular/core'; 163 | 164 | @Component({ 165 | selector: 'app-root', 166 | template: ` 167 | hi 168 | `, 169 | styles: [ 170 | `b { 171 | color: red; 172 | }` 173 | ] 174 | }) 175 | export class AppComponent { 176 | } 177 | ``` 178 | 179 | `app.component.spec.ts` file contains information about tests. We will ignore it just for now. 180 | 181 | In angular projects works under modules. These modules look like `java packages` or `c# namespaces`. Your components defined in a module. `app.module.ts` file contains our main module. 182 | 183 | ```ts 184 | import { BrowserModule } from '@angular/platform-browser'; 185 | import { NgModule } from '@angular/core'; 186 | import { FormsModule } from '@angular/forms'; 187 | import { HttpModule } from '@angular/http'; 188 | 189 | import { AppComponent } from './app.component'; 190 | 191 | @NgModule({ 192 | declarations: [ 193 | AppComponent 194 | ], 195 | imports: [ 196 | BrowserModule, 197 | FormsModule, 198 | HttpModule 199 | ], 200 | providers: [], 201 | bootstrap: [AppComponent] 202 | }) 203 | export class AppModule { } 204 | ``` 205 | 206 | All components that using in this project should declared in this file. If we don't declare it, angular couldn't find component that we want to use. 207 | 208 | Rightnow I won't explain other files that we didn't check. We will come to them too. 209 | 210 | > Before going deeper I recommend to learn typescript. If you don't have a clue about it please check it. 211 | 212 | 213 | ### Creating a new component 214 | 215 | To create new component; first create a folder inside of `./src/app/` folder. We name it `server`. 216 | 217 | Inside of this folder create a file that called `server.component.ts`. Also you may create `server.component.html` too. 218 | 219 | In server.component.ts; 220 | 221 | ```ts 222 | export class ServerComponent { 223 | 224 | } 225 | ``` 226 | 227 | We created a class that named `ServerComponent`. This class should exported out. We can't use if we didn't export it. we still have to do some stuff. We have to create a `decorator` that decorates this class is a `Component`. So lets do it? 228 | 229 | ```ts 230 | @Component({ 231 | 232 | }) 233 | export class ServerComponent { 234 | 235 | } 236 | ``` 237 | 238 | But it won't compile. We have to import something.. `Component` decorator is defined in `@angular/core` package. We can import it from this package by like this. 239 | 240 | ```ts 241 | import { Component } from '@angular/core'; 242 | 243 | @Component({ 244 | 245 | }) 246 | export class ServerComponent { 247 | 248 | } 249 | ``` 250 | 251 | Now we created a component that angular could use. But still it is invalid. Because it's like untitled subject. It just there but no one could call it. So we have to declare some `selector`. 252 | 253 | ```ts 254 | import { Component } from '@angular/core'; 255 | 256 | @Component({ 257 | selector: 'app-server' 258 | }) 259 | export class ServerComponent { 260 | 261 | } 262 | ``` 263 | 264 | `selector` is similiar to css selector. If you just put something in there like this `app-server`; it would look for ``. If you put there `.app-server` then you get `
`. You can even use `[app-server]` to look for properties. (like `
`). 265 | 266 | 267 | We have to bind component's html file to component itself. We can use `templateUrl`. It is same as `app.component`. 268 | 269 | ```ts 270 | import {Component} from '@angular/core'; 271 | 272 | @Component({ 273 | selector: 'app-server', 274 | templateUrl: './server.component.html' 275 | }) 276 | export class ServerComponent { 277 | 278 | } 279 | ``` 280 | 281 | To use this component we have to add it to `app.module.ts`. 282 | 283 | 284 | ```ts 285 | import { BrowserModule } from '@angular/platform-browser'; 286 | import { NgModule } from '@angular/core'; 287 | import { FormsModule } from '@angular/forms'; 288 | import { HttpModule } from '@angular/http'; 289 | 290 | import { AppComponent } from './app.component'; 291 | import { ServerComponent } from './server/server.component' // <<-- import first 292 | 293 | @NgModule({ 294 | declarations: [ 295 | AppComponent, 296 | ServerComponent // <<-- we have to add component here 297 | ], 298 | imports: [ 299 | BrowserModule, 300 | FormsModule, 301 | HttpModule 302 | ], 303 | providers: [], 304 | bootstrap: [AppComponent] 305 | }) 306 | export class AppModule { } 307 | 308 | ``` 309 | 310 | I will change `server.component.html` 311 | 312 | ```html 313 | server component 314 | ``` 315 | 316 | Now we can use this component. Create a new element in `app.component.html`. 317 | 318 | ```html 319 | app component 320 | 321 | 322 | ``` 323 | 324 | Check out [http://localhost:8080](http://localhost:8080) now. 325 | 326 | ![](images/1.png) 327 | 328 | ### Create component with cli 329 | 330 | Sometimes we don't want to create basic structures over and over again. So `@angular/cli` has a solution. Using generate function of `ng` we can create components without any labor. 331 | 332 | ``` 333 | ng generate component 334 | or 335 | ng g c 336 | ``` 337 | 338 | for example, If we want to create servers component; 339 | 340 | ``` 341 | ng generate component servers 342 | ``` 343 | 344 | Will generate `servers` folder in `app` folder and It will create `ts`, `html`, `css` and `.spec.ts` files automaticly. Also it will add declaration to `app.module.ts`. Basically it makes component ready to use. 345 | 346 | 347 | 348 | ### Including bootstrap css to project 349 | 350 | We may need bootstrap for our project. How we import it? First we have to download the package. 351 | 352 | ``` 353 | npm install bootstrap --save 354 | ``` 355 | 356 | Then open the `.angular-cli.json` file. Modify it like this; 357 | 358 | ```js 359 | { 360 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 361 | "project": { 362 | "version": "1.0.0-beta.32.3", 363 | "name": "new-cli" 364 | }, 365 | "apps": [ 366 | { 367 | "root": "src", 368 | "outDir": "dist", 369 | "assets": [ 370 | "assets", 371 | "favicon.ico" 372 | ], 373 | "index": "index.html", 374 | "main": "main.ts", 375 | "polyfills": "polyfills.ts", 376 | "test": "test.ts", 377 | "tsconfig": "tsconfig.json", 378 | "prefix": "app", 379 | "styles": [ 380 | "../node_modules/bootstrap/dist/css/bootstrap.min.css", // <<-- we add this line 381 | "styles.css" 382 | ], 383 | "scripts": [], 384 | "environmentSource": "environments/environment.ts", 385 | "environments": { 386 | "dev": "environments/environment.ts", 387 | "prod": "environments/environment.prod.ts" 388 | } 389 | } 390 | ], 391 | "e2e": { 392 | "protractor": { 393 | "config": "./protractor.conf.js" 394 | } 395 | }, 396 | "lint": [ 397 | { 398 | "files": "src/**/*.ts", 399 | "project": "src/tsconfig.json" 400 | }, 401 | { 402 | "files": "e2e/**/*.ts", 403 | "project": "e2e/tsconfig.json" 404 | } 405 | ], 406 | "test": { 407 | "karma": { 408 | "config": "./karma.conf.js" 409 | } 410 | }, 411 | "defaults": { 412 | "styleExt": "css", 413 | "component": {} 414 | } 415 | } 416 | 417 | ``` 418 | 419 | Now you can use bootstrap. 420 | 421 | >**Note:** There is a library for [bootstrap](https://github.com/ng-bootstrap/ng-bootstrap). It basically provides components too. 422 | 423 | 424 | ### Databinding 425 | 426 | Databinding is basically binding datas between template and class. 427 | 428 | * **OUT** String Interpolation: Bind a variable to template. Syntax `{{ data }}` 429 | * **OUT** Property Binding: Bind a variable to template's property. Syntax `[property]="data"` 430 | * **IN** Event Binding: Bind a event to class. Syntax `(event)="expression"` 431 | 432 | #### String Interpolation 433 | 434 | Lets a create basic component that writes a name. Name should provided with String Interpolation from a variable that we define in class. 435 | 436 | ```ts 437 | import { Component } from '@angular/core'; 438 | 439 | @Component({ 440 | selector: 'app-name', 441 | template: ` 442 |

My name is {{name}}

443 | ` 444 | }) 445 | export class NameComponent { 446 | name: string = "Doğan"; 447 | } 448 | ``` 449 | 450 | Output: 451 | 452 | ![](images/2.png) 453 | 454 | 455 | This time lets add a 1 second timeout. After 1 second we will change the name to "Göksel" 456 | 457 | ```ts 458 | import { Component } from '@angular/core'; 459 | 460 | @Component({ 461 | selector: 'app-name', 462 | template: ` 463 |

My name is {{name}}

464 | ` 465 | }) 466 | export class NameComponent { 467 | name: string = "Doğan"; 468 | 469 | constructor() { 470 | setTimeout(() => { 471 | this.name = "Göksel"; 472 | }, 1000); 473 | } 474 | } 475 | ``` 476 | 477 | In the beginning it will show you ` My name is Doğan ` but after 1 second you will get ` My name is Göksel `. Databinding makes template render again. So you don't care rendering mechanism. 478 | 479 | #### Property binding and Event Binding 480 | 481 | This time we will use other binding types too. 482 | 483 | ```ts 484 | import { Component } from '@angular/core'; 485 | 486 | @Component({ 487 | selector: 'app-name', 488 | template: ` 489 | 490 | 491 | ` 492 | }) 493 | export class NameComponent { 494 | isDisabled = true; 495 | 496 | someAction() { 497 | alert("hello"); 498 | } 499 | 500 | changeDisabled() { 501 | this.isDisabled = !this.isDisabled; // reverse the value 502 | } 503 | } 504 | ``` 505 | 506 | At the beginning regular button isn't clickable. But when we click second button it will be enabled and you get alert "hello" when you click it. 507 | 508 | #### Two way databinding 509 | 510 | There is one more databinding type of angular. Its called `Two way databinding`. This time events, properties and classes binded. 511 | 512 | 513 | ```ts 514 | import { Component } from '@angular/core'; 515 | 516 | @Component({ 517 | selector: 'app-name', 518 | template: ` 519 | 520 | 521 |

My name is {{name}}

522 | ` 523 | }) 524 | export class NameComponent { 525 | name: string = "Doğan"; 526 | } 527 | ``` 528 | 529 | You will see that when input change class's name will automaticly change and then `My name is ____` will automaticly render back. If you change name from class then input's value will change too. 530 | 531 | > **Note:** `ngModel` should be imported in `app.module.ts` file. Required module is `FormsModule`. 532 | 533 | ### Directives 534 | 535 | There are 3 kinds of directives. 536 | 537 | * Components 538 | * Structural Directives (you will see this as star `*` character) 539 | * Attribute Directives 540 | 541 | You already know the components. Lets dive into structural directives. 542 | 543 | These directives are control full of dom. You may ask why? 544 | 545 | #### ngIf 546 | 547 | Lets check an example of `*ngIf` 548 | 549 | 550 | ```ts 551 | import { Component } from '@angular/core'; 552 | 553 | @Component({ 554 | selector: 'app-name', 555 | template: ` 556 | 557 |

558 | I'm visible now 559 |

560 | ` 561 | }) 562 | export class NameComponent { 563 | visible: boolean = false; 564 | } 565 | ``` 566 | 567 | In this example when you click the button, some text appears. But interesting part is when visible is false, p element won't exist. It will be created when visible is true. Structural directives modify current dom and remove. 568 | 569 | You can use else syntax (Angular 4) too. 570 | 571 | 572 | ```ts 573 | import { Component } from '@angular/core'; 574 | 575 | @Component({ 576 | selector: 'app-name', 577 | template: ` 578 | 579 |

580 | I'm visible now 581 |

582 | 583 |

584 | I'm hidden 585 |

586 |
587 | 588 | ` 589 | }) 590 | export class NameComponent { 591 | visible: boolean = false; 592 | } 593 | ``` 594 | 595 | Please try it before continue. 596 | 597 | #### ngFor 598 | 599 | ngFor is a structural directive too. It will modify and clone itself as given array. For example; 600 | 601 | ```ts 602 | import { Component } from '@angular/core'; 603 | 604 | @Component({ 605 | selector: 'app-name', 606 | template: ` 607 | 610 | ` 611 | }) 612 | export class NameComponent { 613 | cars = [ 614 | 'Toyota', 615 | 'Honda', 616 | 'Ford' 617 | ] 618 | } 619 | ``` 620 | 621 | ![](images/3.png) 622 | 623 | ngFor also has a index syntax. If you use a `;` character then define a variable that equals the index; you can use the index in the scope. 624 | 625 | ```ts 626 | import { Component } from '@angular/core'; 627 | 628 | @Component({ 629 | selector: 'app-name', 630 | template: ` 631 | 634 | ` 635 | }) 636 | export class NameComponent { 637 | cars = [ 638 | 'Toyota', 639 | 'Honda', 640 | 'Ford' 641 | ] 642 | } 643 | ``` 644 | 645 | ![](images/4.png) 646 | 647 | 648 | #### ngStyle 649 | 650 | ngStyle is an attribute directive. It doesn't like structural directives. 651 | 652 | ```ts 653 | import { Component } from '@angular/core'; 654 | 655 | @Component({ 656 | selector: 'app-name', 657 | template: ` 658 | 661 | ` 662 | }) 663 | export class NameComponent { 664 | cars = [ 665 | { 666 | name: 'Toyota', 667 | total: 1 668 | }, 669 | { 670 | name: 'Ford', 671 | total: 0 672 | } 673 | ] 674 | } 675 | ``` 676 | 677 | You will see that Toyota item will green but Ford item will red. 678 | 679 | #### ngClass 680 | 681 | ngClass is an attribute directive too. 682 | 683 | ```ts 684 | import { Component } from '@angular/core'; 685 | 686 | @Component({ 687 | selector: 'app-name', 688 | template: ` 689 | 692 | `, 693 | 694 | styles: [ 695 | `.notInStock { 696 | background-color: red 697 | }` 698 | ] 699 | }) 700 | export class NameComponent { 701 | cars = [ 702 | { 703 | name: 'Toyota', 704 | total: 1 705 | }, 706 | { 707 | name: 'Ford', 708 | total: 0 709 | }, 710 | ] 711 | } 712 | ``` 713 | 714 | You will see that Toyota item will looking normal but Ford item will be red. 715 | 716 | #### ngSwitch 717 | 718 | ngSwitch is for switching between multiple cases. Its very usefull built-in directive. 719 | 720 | ```ts 721 | import { Component } from '@angular/core'; 722 | 723 | @Component({ 724 | selector: 'app-name', 725 | template: ` 726 |
727 |

Count is 5

728 |

Count is 10

729 |

Count is Default

730 |
731 | ` 732 | }) 733 | export class NameComponent { 734 | count: number = 5; 735 | } 736 | ``` 737 | 738 | 739 | ### Input 740 | 741 | In this chapter our goal is making some property to accessible from outside. You may ask why we need this? We creating components that has own scope. For example we create "create new user" component and "user list" component. So one component must effect to another one. 742 | 743 | First lets do what we wanted. We will create some components. 744 | 745 | ```bash 746 | ng new my-second-app 747 | cd my-second-app 748 | ng g c users --spec false #-- spec false blocks spec file generation 749 | ng g c users/user-list --spec false # users/list syntax will create a component in users folder. 750 | ng g c users/user-item --spec false 751 | ng g c users/user-create --spec false 752 | ``` 753 | 754 | Edit app.component.html as this 755 | 756 | ```html 757 | 758 | ``` 759 | 760 | 761 | Edit users.component.html as this 762 | 763 | ```html 764 | 765 |
766 | 767 | ``` 768 | 769 | Add an array to user-list component file. 770 | 771 | ```ts 772 | import { Component, OnInit } from '@angular/core'; 773 | 774 | @Component({ 775 | selector: 'app-user-list', 776 | templateUrl: './user-list.component.html', 777 | styleUrls: ['./user-list.component.css'] 778 | }) 779 | export class UserListComponent implements OnInit { 780 | users = ['Jack', 'George', 'Another common name']; // << this line 781 | 782 | constructor() { } 783 | 784 | ngOnInit() { 785 | } 786 | } 787 | ``` 788 | 789 | Edit user-list.component.html as this 790 | 791 | ```html 792 | 793 | ``` 794 | 795 | Edit user-item.component.html and user-item.component.ts as like this. 796 | 797 | ```html 798 |

799 | User name: {{name}} 800 | 801 | 802 |

803 | ``` 804 | 805 | ```ts 806 | import { Component, OnInit } from '@angular/core'; 807 | 808 | @Component({ 809 | selector: 'app-user-item', 810 | templateUrl: './user-item.component.html', 811 | styleUrls: ['./user-item.component.css'] 812 | }) 813 | export class UserItemComponent implements OnInit { 814 | name: string; 815 | constructor() { } 816 | 817 | ngOnInit() { 818 | } 819 | 820 | } 821 | ``` 822 | 823 | So now we ready to process. If you get this point you probably see this screen. 824 | 825 | ![](images/5.png) 826 | 827 | User fields are created but name seems doesn't work at all. We have to do something don't we. UserItemComponent element's name property cannot be accessed by other component because it works in own closure. We have to add a decorator to access. Its called `@Input` 828 | 829 | We now editing user.component.ts 830 | 831 | 832 | ```ts 833 | import { Component, OnInit } from '@angular/core'; 834 | 835 | @Component({ 836 | selector: 'app-user-item', 837 | templateUrl: './user-item.component.html', 838 | styleUrls: ['./user-item.component.css'] 839 | }) 840 | export class UserItemComponent implements OnInit { 841 | @Input() name: string; 842 | constructor() { } 843 | 844 | ngOnInit() { 845 | } 846 | 847 | } 848 | ``` 849 | 850 | `@Input` decorator is actually decorator generating function. So we have to call it like `@Input()`. You can use the first parameter as alias. I will give you an example for it too. 851 | 852 | Now we test our application but result is same. Nothing changed :worried: 853 | 854 | ![](images/5.png) 855 | 856 | We forgot to set name because we never set it or access it from outside of user-item component. 857 | 858 | Edit the user-list.component.html 859 | 860 | ```html 861 | 862 | ``` 863 | 864 | As you can see, we used a property binding. Basically `@Input` working as property. We set the value as user, because we declared a variable as `user` in ngFor directive. 865 | 866 | Now give a shot. 867 | 868 | ![](images/6.png) 869 | 870 | Lets check example of the alias parameter `@Input()`. 871 | 872 | app-user-item.ts 873 | 874 | ```ts 875 | import { Component, OnInit } from '@angular/core'; 876 | 877 | @Component({ 878 | selector: 'app-user-item', 879 | templateUrl: './user-item.component.html', 880 | styleUrls: ['./user-item.component.css'] 881 | }) 882 | export class UserItemComponent implements OnInit { 883 | @Input('user') name: string; // << as you can see we give some parameter 884 | constructor() { } 885 | 886 | ngOnInit() { 887 | } 888 | 889 | } 890 | ``` 891 | 892 | Now component looking for `user` property. 893 | 894 | 895 | Edit the user-list.component.html 896 | 897 | ```html 898 | 899 | ``` 900 | 901 | ### Output 902 | 903 | Last chapter we dive into Input. In our example we created edit and delete buttons. Also we must have a working user-create component too. Lets check it. 904 | 905 | user-create.component.html 906 | 907 | ```html 908 | name: 909 | 910 | ``` 911 | 912 | user-create.component.ts 913 | 914 | ```ts 915 | import { Component, OnInit, Output, EventEmitter } from '@angular/core'; 916 | 917 | @Component({ 918 | selector: 'app-user-create', 919 | templateUrl: './user-create.component.html', 920 | styleUrls: ['./user-create.component.css'] 921 | }) 922 | export class UserCreateComponent implements OnInit { 923 | 924 | constructor() { } 925 | 926 | ngOnInit() { 927 | } 928 | 929 | name: string; // two-way-binding property 930 | 931 | @Output() 932 | onUserCreated = new EventEmitter(); // this is the our event that can be binded out of this component 933 | // note: EventEmitter should be imported from @angular/core 934 | 935 | onUserCreate() { // this function get trigger when user click button 936 | this.onUserCreated.emit(this.name); // we send data to eventemitter 937 | } 938 | } 939 | ``` 940 | 941 | > **Note:** I will move users to upper component. 942 | 943 | users.component.html 944 | 945 | ```html 946 | 947 |
948 | 949 | ``` 950 | 951 | users.component.ts 952 | 953 | ```ts 954 | import { Component, OnInit } from '@angular/core'; 955 | 956 | @Component({ 957 | selector: 'app-users', 958 | templateUrl: './users.component.html', 959 | styleUrls: ['./users.component.css'] 960 | }) 961 | export class UsersComponent implements OnInit { 962 | users = ['Jack', 'George', 'Another common name']; 963 | 964 | constructor() { } 965 | 966 | ngOnInit() { 967 | } 968 | 969 | onUserCreated(name) { 970 | this.users.push(name); 971 | } 972 | } 973 | ``` 974 | 975 | user-list.component.ts 976 | 977 | ```ts 978 | import { Component, OnInit, Input } from '@angular/core'; 979 | 980 | @Component({ 981 | selector: 'app-user-list', 982 | templateUrl: './user-list.component.html', 983 | styleUrls: ['./user-list.component.css'] 984 | }) 985 | export class UserListComponent implements OnInit { 986 | @Input() // added this 987 | users; 988 | 989 | constructor() { } 990 | 991 | ngOnInit() { 992 | } 993 | 994 | } 995 | ``` 996 | 997 | Lets check our application. We type some name to input. Then click the create button. :sunglasses: 998 | 999 | ### View Encapsulation 1000 | 1001 | Component's css files are specific to component. For example in css file; 1002 | 1003 | ```css 1004 | b { 1005 | color: red; 1006 | } 1007 | ``` 1008 | 1009 | This css compiled with some property selector so this way other components b element won't get any effect but you may don't want to do that. Simply changing encapsulation can modify this feature. 1010 | 1011 | ```ts 1012 | import { Component, ViewEncapsulation } from '@angular/core'; 1013 | 1014 | @Component({ 1015 | selector: 'app-some', 1016 | templateUrl: './some.component.html', 1017 | styleUrls: ['./some.component.css'], 1018 | encapsulation: ViewEncapsulation.None 1019 | }) 1020 | export class SomeComponent { 1021 | 1022 | } 1023 | ``` 1024 | 1025 | ### Local reference 1026 | 1027 | Local reference makes a marking for DOM elements. We use that in `*ngIf` structure directive section. There is one more thing that I should write and thats named `@ViewChild` decorator. 1028 | 1029 | This decorator allows to access DOM element from code. If you know what are you going to do then you can use this decorator, otherwise please avoid using this feature. 1030 | 1031 | ```ts 1032 | import { Component, ViewChild, ElementRef } from '@angular/core'; 1033 | 1034 | @Component({ 1035 | selector: 'app-some', 1036 | template: ` 1037 |
1038 | 1039 |
1040 | ` 1041 | }) 1042 | export class SomeComponent { 1043 | @ViewChild('localReference') 1044 | localReferenceDiv: ElementRef; 1045 | } 1046 | ``` 1047 | 1048 | 1049 | ### ng-content 1050 | 1051 | ng-content is a special directive that provide element's content. Normally angular will override the content of components. `Loading...` is good example for this consept. When angular handle `app-root` then `Loading` text will disapear. But what if we want to show it. 1052 | 1053 | Let me show you an example. 1054 | 1055 | ```ts 1056 | import { Component } from '@angular/core'; 1057 | 1058 | @Component({ 1059 | selector: 'app-bold', 1060 | template: ` 1061 | 1062 | 1063 | 1064 | ` 1065 | }) 1066 | export class BoldComponent { 1067 | } 1068 | ``` 1069 | 1070 | ```ts 1071 | import { Component } from '@angular/core'; 1072 | 1073 | @Component({ 1074 | selector: 'app-root', 1075 | template: ` 1076 | this text will be bold 1077 | ` 1078 | }) 1079 | export class AppComponent { 1080 | } 1081 | ``` 1082 | 1083 | > **Note:** Last chapter we learnt ViewChild. If you want to use ViewChild in a content it won't work. You have to use `@ContentChild` 1084 | 1085 | ### Life cycle of components 1086 | 1087 | Components have a standard life cycle. They all have these things. We can hook them. 1088 | 1089 | * ngOnChanges: Called after a bound input proerty changes 1090 | * ngOnInit: Called once the component initalized 1091 | * ngDoCheck: Called during every change detection run 1092 | * ngAfterContentInit: Called after content (ng-content) has been projected into view 1093 | * ngAfterContentChecked: Called every time the projected content has been checked 1094 | * ngAfterViewInit: Called after the component's view (and child views) has been initalized. 1095 | * ngAfterViewChecked: Called every time the view (and child views) has been checked. 1096 | * ngOnDestroy: Called once the components is about the be destroyed. 1097 | 1098 | ```ts 1099 | import { Component, OnInit, OnChanges, SimpleChanges, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy } from '@angular/core'; 1100 | 1101 | @Component({ 1102 | selector: 'app-some', 1103 | template: ` ` 1104 | }) 1105 | export class SomeComponent implements OnInit, OnChanges, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy { 1106 | 1107 | ngOnChanges(changes: SimpleChanges): void { 1108 | console.log('ngOnChanges', changes); 1109 | } 1110 | 1111 | ngOnInit(): void { 1112 | console.log('ngOnInit'); 1113 | } 1114 | 1115 | ngDoCheck(): void { 1116 | console.log('ngDoCheck'); 1117 | } 1118 | 1119 | ngAfterContentInit(): void { 1120 | console.log('ngAfterContentInit'); 1121 | } 1122 | 1123 | ngAfterContentChecked(): void { 1124 | console.log('ngAfterContentChecked'); 1125 | } 1126 | 1127 | ngAfterViewChecked(): void { 1128 | console.log('ngAfterViewChecked'); 1129 | } 1130 | 1131 | ngAfterViewInit(): void { 1132 | console.log('ngAfterViewInit'); 1133 | } 1134 | 1135 | ngOnDestroy(): void { 1136 | console.log('ngOnDestroy'); 1137 | } 1138 | } 1139 | ``` 1140 | 1141 | 1142 | ### Creating a new directive 1143 | 1144 | We saw some already defined directives. But how we can defire new? This chapter we will dive into that. 1145 | 1146 | Directives are defining just like components. You have to add them to app.module.ts. We can create manual but I will use @angular/cli. 1147 | 1148 | ``` 1149 | ng generate directive 1150 | or 1151 | ng g d 1152 | ``` 1153 | 1154 | I will create a green directive that makes elements green on hover. 1155 | 1156 | ``` 1157 | ng g d green 1158 | ``` 1159 | 1160 | I remove spec.ts file because we don't care tests just now. There should be green.directive.ts file. Directive files are created as `.directive.ts` syntax. 1161 | 1162 | ```ts 1163 | import { Directive } from '@angular/core'; 1164 | 1165 | @Directive({ 1166 | selector: '[appGreen]' 1167 | }) 1168 | export class GreenDirective { 1169 | constructor() { } 1170 | } 1171 | ``` 1172 | 1173 | This directive will handle the `appGreen` property. If you use somewhere else this then directive will bound to element. 1174 | 1175 | #### HostListener 1176 | 1177 | We trying to make green element whenever mouse hover's the element so we have to catch the events. 1178 | 1179 | ```ts 1180 | import { Directive, HostListener } from '@angular/core'; 1181 | 1182 | @Directive({ 1183 | selector: '[appGreen]' 1184 | }) 1185 | export class GreenDirective { 1186 | constructor() { } 1187 | 1188 | @HostListener('mouseenter') 1189 | mouseenter() { 1190 | // mouse enters 1191 | } 1192 | 1193 | @HostListener('mouseleave') 1194 | mouseleave() { 1195 | // mouse leaves 1196 | } 1197 | } 1198 | ``` 1199 | 1200 | #### HostBinding 1201 | 1202 | How about to change colors? Now we use `@HostBinding`. 1203 | 1204 | ```ts 1205 | import { Directive, HostBinding, HostListener } from '@angular/core'; 1206 | 1207 | @Directive({ 1208 | selector: '[appGreen]' 1209 | }) 1210 | export class GreenDirective { 1211 | @HostBinding('style.backgroundColor') backgroundColor: string = 'transparent'; 1212 | 1213 | @HostListener('mouseenter') 1214 | mouseenter() { 1215 | this.backgroundColor = 'green'; 1216 | } 1217 | 1218 | @HostListener('mouseleave') 1219 | mouseleave() { 1220 | this.backgroundColor = 'transparent'; 1221 | } 1222 | } 1223 | ``` 1224 | 1225 | ### Services and dependency injection 1226 | 1227 | Services useful to carry data between components. We do not require any decorator to create service. Lets create an user service. 1228 | 1229 | I recommend to create file as `.service.ts` syntax. 1230 | 1231 | So lets create a new users.service.ts file on `app` folder. 1232 | 1233 | ```ts 1234 | export class UserService { 1235 | users = [ 1236 | {id: 1, name: 'co3moz'}, 1237 | {id: 2, name: 'goxel'} 1238 | {id: 3, name: 'Ilrkhoaktul'} 1239 | ] 1240 | 1241 | getUsers() { 1242 | return this.users; 1243 | } 1244 | 1245 | addUser(user: {id: number, name: string}) { 1246 | this.users.push(user); 1247 | } 1248 | 1249 | removeUser(id: number) { 1250 | this.users.splice(id, 1); 1251 | } 1252 | } 1253 | ``` 1254 | 1255 | We basically create an users service class with some property and functions. 1256 | 1257 | Lets use it from a component. 1258 | 1259 | ```ts 1260 | import { UserService } from 'user.service'; 1261 | import { Component } from '@angular/core'; 1262 | 1263 | @Component({ 1264 | selector: 'app-user-list', 1265 | template: ` 1266 |

{{ user.name }}

1267 | `, 1268 | providers: [ 1269 | UserService 1270 | ] 1271 | }) 1272 | export class UserListComponent implements OnInit { 1273 | users; 1274 | constructor(private userService: UserService) {} // userService's type must be declared. Otherwise it won't work. 1275 | 1276 | ngOnInit() { 1277 | this.users = this.userService.getUsers(); // pass reference of array to local variable. 1278 | } 1279 | } 1280 | ``` 1281 | 1282 | > **Important Note:** Providers will provide a service to component but every creation of userlistComponent will make own UserService. Because we said to component when you initializing create a new service that called UserService. But what if we just want to application wide? We may need to use this datas from outside of this component. We have to use app.module.ts file for this job. Inside of app.module.ts there is providers section that we can put our service. 1283 | 1284 | > **Important Note 2:** Children of userListComponent can access same service if they didn't declared a new provider of UserService. So Providers section of component should be used only for creating new provider. 1285 | 1286 | You can use `@angular/cli` to generate service 1287 | 1288 | ``` 1289 | ng generate service 1290 | or 1291 | ng g s 1292 | ``` 1293 | 1294 | #### Injecting a service into another service 1295 | 1296 | We may need a service inside of another service. For example we may have a logging service and this service may required to other places. So how we use another service in our service? 1297 | 1298 | There you go, some example of `@Injectable` 1299 | 1300 | ```ts 1301 | import { LoggingService } from 'logging.service'; 1302 | import { Injectable } from '@angular/core'; 1303 | 1304 | @Injectable() 1305 | export class UserService { 1306 | users = [ 1307 | {id: 1, name: 'co3moz'}, 1308 | {id: 2, name: 'goxel'} 1309 | {id: 3, name: 'Ilrkhoaktul'} 1310 | ]; 1311 | 1312 | constructor(private loggingService: LoggingService) { 1313 | 1314 | } 1315 | 1316 | getUsers() { 1317 | return this.users; 1318 | } 1319 | 1320 | addUser(user: {id: number, name: string}) { 1321 | this.users.push(user); 1322 | this.loggingService.log('user added'); 1323 | } 1324 | 1325 | removeUser(id: number) { 1326 | this.users.splice(id, 1); 1327 | this.loggingService.log('user removed'); 1328 | } 1329 | } 1330 | ``` 1331 | 1332 | 1333 | #### Event emitting service 1334 | 1335 | We may need a event that emits some information. 1336 | 1337 | ```ts 1338 | import { LoggingService } from 'logging.service'; 1339 | import { Injectable, EventEmitter } from '@angular/core'; 1340 | 1341 | @Injectable() 1342 | export class UserService { 1343 | users = [ 1344 | {id: 1, name: 'co3moz'}, 1345 | {id: 2, name: 'goxel'} 1346 | {id: 3, name: 'Ilrkhoaktul'} 1347 | ]; 1348 | 1349 | constructor(private loggingService: LoggingService) { 1350 | 1351 | } 1352 | 1353 | userCreated = new EventEmitter<{id: number, name: string}>(); 1354 | 1355 | getUsers() { 1356 | return this.users; 1357 | } 1358 | 1359 | addUser(user: {id: number, name: string}) { 1360 | this.users.push(user); 1361 | this.userCreated.emit(user); 1362 | this.loggingService.log('user added'); 1363 | } 1364 | 1365 | removeUser(id: number) { 1366 | this.users.splice(id, 1); 1367 | this.loggingService.log('user removed'); 1368 | } 1369 | } 1370 | ``` 1371 | 1372 | In component we can just subscribe the event. We will learn better feature so this feature is just for knowledge. 1373 | 1374 | ```ts 1375 | import { UserService } from 'user.service'; 1376 | import { Component } from '@angular/core'; 1377 | 1378 | @Component({ 1379 | selector: 'app-user-list', 1380 | template: ` 1381 |

{{ user.name }}

1382 | `, 1383 | providers: [ 1384 | UserService 1385 | ] 1386 | }) 1387 | export class UserListComponent implements OnInit { 1388 | users; 1389 | constructor(private userService: UserService) { 1390 | this.userService.userCreated.subscribe((user) => { 1391 | console.log('new user just created'); 1392 | }); 1393 | } // userService's type must be declared. Otherwise it won't work. 1394 | 1395 | ngOnInit() { 1396 | this.users = this.userService.getUsers(); // pass reference of array to local variable. 1397 | } 1398 | } 1399 | ``` 1400 | 1401 | > **Important Note:** When you subscribing manually don't forget to unsubscribe with `ngOnDestroy`. 1402 | 1403 | 1404 | ### Router 1405 | 1406 | Router is routes components as pages. To you router first go `app.module.ts` 1407 | 1408 | Import the Routes from `@angular/router` 1409 | 1410 | ```ts 1411 | import { Routes, RouterModule } from '@angular/router'; 1412 | ``` 1413 | 1414 | Then create a array that contains following objects. 1415 | 1416 | ```ts 1417 | const appRoutes: Routes = [ 1418 | { path: 'users', component: UsersComponent} 1419 | ]; 1420 | ``` 1421 | 1422 | `path` declares a route in browser. for example `users` makes routes for `/users`. If path given as empty string then it routes for ` ` so this means we can make a home page. 1423 | 1424 | ```ts 1425 | const appRoutes: Routes = [ 1426 | { path: '', component: HomeComponent}, 1427 | { path: 'users', component: UsersComponent} 1428 | ]; 1429 | ``` 1430 | 1431 | Also you must add `RouterModule.forRoot(appRoutes)` to imports section of `AppModule`. 1432 | 1433 | > **Note** You may create a `app.route.ts` or `app.routing.ts` file. Its your decision. 1434 | 1435 | Now we have to declare where will content go? we will use ``. 1436 | 1437 | I will add this to app.component.html. 1438 | 1439 | #### Links 1440 | 1441 | In this sub-chapter we will learn router links. 1442 | 1443 | Normally to make link we simple use `href`. 1444 | 1445 | ```html 1446 | Home 1447 | ``` 1448 | 1449 | But for angular its invalid because every click causes full page reload. Our application must be stable as possible as can. 1450 | 1451 | We will use `routerLink` directive. 1452 | 1453 | ```html 1454 | Home 1455 | ``` 1456 | 1457 | You may use `[]` syntax for expressions. 1458 | 1459 | ```html 1460 | Home 1461 | ``` 1462 | 1463 | #### Active route 1464 | 1465 | We may need to style active page or etc. To archive this we will use `routerLinkActive`. 1466 | 1467 | ```html 1468 |
1469 | Home 1470 |
1471 | ``` 1472 | 1473 | routerLinkActive directive has a another directive that named `routerLinkActiveOptions`. With routerLinkActiveOptions we can give options to routerLinkActive. For example for full path check; 1474 | 1475 | ```html 1476 |
1477 | Home 1478 |
1479 | ``` 1480 | 1481 | #### Navigating from code 1482 | 1483 | Accesing the router from a component might be useful sometimes. 1484 | 1485 | ```ts 1486 | import { Component } from '@angular/core'; 1487 | import { Router } from '@angular/router'; 1488 | 1489 | @Component({ 1490 | selector: 'app-user-list', 1491 | template: `` 1492 | }) 1493 | export class UserListComponent { 1494 | constructor(private router: Router) { 1495 | } 1496 | 1497 | navigateSomewhereElse() { 1498 | this.router.navigate(['/home']); 1499 | } 1500 | 1501 | } 1502 | ``` 1503 | 1504 | 1505 | #### Parameters of routes 1506 | 1507 | Examples can show everything. 1508 | 1509 | ```ts 1510 | const appRoutes: Routes = [ 1511 | { path: '', component: HomeComponent}, 1512 | { path: 'users/:id', component: UsersComponent} 1513 | ]; 1514 | ``` 1515 | 1516 | ```ts 1517 | import { Component } from '@angular/core'; 1518 | import { ActivatedRoute } from '@angular/router'; 1519 | 1520 | @Component({ 1521 | selector: 'app-user-list', 1522 | template: `` 1523 | }) 1524 | export class UsersComponent { 1525 | constructor(private route: ActivatedRoute) { 1526 | } 1527 | 1528 | getIdParameter() { 1529 | return this.route.snapshot.params['id']; 1530 | } 1531 | 1532 | } 1533 | ``` 1534 | 1535 | #### Nested routes 1536 | 1537 | Nested routes are useful when we need show multiple components at same time. 1538 | 1539 | ```ts 1540 | const appRoutes: Routes = [ 1541 | { path: '', component: HomeComponent }, 1542 | { path: 'users', component: UsersComponent, children: [ 1543 | { path: ':id', component: UserComponent }, 1544 | { path: ':id/edit', component: UserEditComponent } 1545 | ]} 1546 | ]; 1547 | ``` 1548 | 1549 | Don't forget to add `` to parent component. 1550 | 1551 | 1552 | #### Redirecting 1553 | 1554 | We may need a redirecting route. I achive that we simple add a route which doesn't have component property. It needs only `redirectTo` parameter. 1555 | 1556 | ```ts 1557 | const appRoutes: Routes = [ 1558 | { path: '', component: HomeComponent }, 1559 | { path: 'users', component: UsersComponent }, 1560 | { path: 'people', redirectTo: '/users' } 1561 | ]; 1562 | ``` 1563 | 1564 | With this feature and wildcard feature we can make 404 pages. 1565 | 1566 | 1567 | ```ts 1568 | const appRoutes: Routes = [ 1569 | { path: '', component: HomeComponent }, 1570 | { path: 'users', component: UsersComponent }, 1571 | { path: 'not-found', component: NotFoundComponent }, 1572 | { path: '**', redirectTo: '/not-found' } // make sure wildcard is at the end. 1573 | ]; 1574 | ``` 1575 | 1576 | Simply other routes will redirected to `NotFoundComponent` 1577 | -------------------------------------------------------------------------------- /images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/co3moz/angular4-notes/f55a058a68d7cb2c8be399bd7a08aa961e38f66e/images/1.png -------------------------------------------------------------------------------- /images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/co3moz/angular4-notes/f55a058a68d7cb2c8be399bd7a08aa961e38f66e/images/2.png -------------------------------------------------------------------------------- /images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/co3moz/angular4-notes/f55a058a68d7cb2c8be399bd7a08aa961e38f66e/images/3.png -------------------------------------------------------------------------------- /images/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/co3moz/angular4-notes/f55a058a68d7cb2c8be399bd7a08aa961e38f66e/images/4.png -------------------------------------------------------------------------------- /images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/co3moz/angular4-notes/f55a058a68d7cb2c8be399bd7a08aa961e38f66e/images/5.png -------------------------------------------------------------------------------- /images/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/co3moz/angular4-notes/f55a058a68d7cb2c8be399bd7a08aa961e38f66e/images/6.png -------------------------------------------------------------------------------- /lang/README.tr.md: -------------------------------------------------------------------------------- 1 | Angular 4 - Notları 2 | ==================== 3 | 4 | Bu kod deposu benim angular 4 notlarımın bir derlemesidir. Angular 2'yi deneyememiştim. Fakat şimdi Angular 4'e bir göz atmaya ve bir ders hazırlamaya karar verdim. Öğrendiğim her şeyi yazacağım, belki bu kod deposu sizin için de rehber olabilir. 5 | 6 | [Maximilian Schwarzmuller](https://www.udemy.com/the-complete-guide-to-angular-2)'e bu harika rehber için teşekkürler. 7 | 8 | > **Yazar notu:** Türkçe çeviriyi üşenmeden yaptığı için [Furkan Başaran](http://github.com/frknbasaran) 'a teşekkürler. 9 | 10 | İçindekiler 11 | ---------------- 12 | 13 | - [Kurulum](#installation) 14 | - [Bir proje yaratmak](#creating-project) 15 | - [Projeyi çalıştırmak](#serving-project) 16 | - [Çalıştırılmış Projeyi İncelemek](#investigating-created-project) 17 | - [Yeni bir komponent oluşturmak](#creating-a-new-component) 18 | - [Komut satırı ile bir komponent oluşturmak](#create-component-with-cli) 19 | - [Projeye bootstrap css eklemek](#including-bootstrap-css-to-project) 20 | - [Databinding](#databinding) 21 | - [Direktifler](#directives) 22 | - [ngIf](#ngif) 23 | - [ngFor](#ngfor) 24 | - [ngStyle](#ngstyle) 25 | - [ngClass](#ngclass) 26 | - [ngSwitch](#ngswitch) 27 | - [Input](#input) 28 | - [Output](#output) 29 | - [View Encapsulation](#view-encapsulation) 30 | - [Yerel Referanslar](#local-reference) 31 | - [ng-content](#ng-content) 32 | - [Komponentlerin Yaşam Döngüsü](#life-cycle-of-components) 33 | - [Yeni bir direktif oluşturmak](#creating-a-new-directive) 34 | - [HostListener](#hostlistener) 35 | - [HostBinding](#hostbinding) 36 | - [Servisler ve Bağlılıkların Zerki](#services-and-dependency-injection) 37 | - [Bir servisi bir başka servise zerk etmek](#injecting-a-service-into-another-service) 38 | - [Olay yayınlama servisi](#event-emitting-service) 39 | - [Router](#router) 40 | - [Links](#links) 41 | - [Active Router](#active-route) 42 | - [Kod içinden yönlendirme](#navigating-from-code) 43 | - [Route Parameters](#parameters-of-routes) 44 | - [Nested Routes](#nested-routes) 45 | - [Yönlendirme](#redirecting) 46 | 47 | ### Kurulum 48 | 49 | Uygulama geliştirmek için ilk önce node.js kurmamız gerekiyor. Eğer node.js nedir bilmiyorsanız Angular 4'ten önce lütfen ona bir göz atın. Biz angular komut satırı eklentisini kullanacağız, bu eklenti bize projelerimizi yaratırken yardımcı olacak. Oldukça kullanışlı bir araç. 50 | 51 | ``` 52 | npm i @angular/cli -g 53 | ``` 54 | 55 | Angular komut satırı paketini `@angular/cli` global parametresiyle yüklemeliyiz. Bu parametre proje lokaline değil global node_modules klasörüne kurulum sağlayacaktır. 56 | 57 | Artık terminalde `ng` komutunu kullanabiliyor olmamız gerek. 58 | 59 | ### Proje yaratmak 60 | 61 | Proje yaratmak için `ng` komutunu kullanacağız. Eğer terminale `ng` yazdığınızda bir hata alıyorsanız `Kurulum` adımında bir hata yapmışsınız demektir, lütfen o adıma gidip işlemleri doğru şekilde tamamladığınızdan emin olun. 62 | 63 | `ng` komutu birden fazla opsiyonel parametreye sahiptir. O konuya da geleceğiz ancak öncelikle bir proje yaratmak için `new` parametresini kullanmalıyız. 64 | 65 | Bu parametre güncel dizinimizde yeni bir proje yapısı oluşturacaktır. Ancak işlem sırasında bir proje ismi vermeliyiz. Ben proje ismi olarak ilk uygulamam anlamına gelen "my-first-app" ismini seçtim. 66 | 67 | ``` 68 | ng new my-first-app 69 | ``` 70 | 71 | Bu komutu kullandıktan sonra terminalimiz `ng` tarafından bazı dosyalar oluşturacak. Ardından gerekli npm paketlerini yükleyecek, işlemler tamamlanana kadar bekleyin. 72 | 73 | ### Projeyi çalıştırmak 74 | 75 | Az önce yeni bir proje oluşturduk. `my-first-app` klasörüne girip `ng` nin `serve` komutunu kullanırsak yüklenen paketler bir http sunucusu oluşturup yayına başlayacaktır. 76 | 77 | ``` 78 | cd my-first-app 79 | ng serve 80 | ``` 81 | 82 | Terminal çıktımızda bir url adresi olmalı. İsterseniz seçiminize bağlı olarak `--port xx` parametresiyle uygulamanın istediğiniz herhangi bir porttan yayınlanmasını sağlayabilirsiniz. 83 | 84 | ``` 85 | ng serve --port 8080 86 | ``` 87 | 88 | Typescript javascript'e çevrildi ve Webpack uygulamanızı paketledi. 89 | Artık localhost:8080 adresnden uygulamaya erişebilirsiniz. 90 | 91 | 92 | ### Çalıştırılmış Projeyi İncelemek 93 | 94 | > Daha fazla derinlere inmeden önce projeyi bir IDE ile açtığınızdan emin olun. Ben Visual Studio Code ya da WebStorm tavsiye ediyorum. 95 | 96 | Proje dizininde `e2e` klasörünü, `src` klasörünü ve birkaç dosyayı göreceğiz. `e2e` klasörünü uçtan uca testleri içerir. Buna daha sonra göz atacağız. (Testlerin kaderi bu.) Projemizin tüm kaynak dosyaları `src` klasöründe bulunur. Diğer dosyalar da proje konfigürasyonlarıyla ilgili bilgileri, paket bağımlılıklarını ve benzeri detayları içerirler. İhtiyaç duyduğumuzda onlarla tekrar ilgileneceğiz. 97 | 98 | `src` klasörünün içinde birden fazla dosya var. Bu dizindeki en önemli dosya `index.html` dosyası. Bu dosya projemizin en üst noktası. Eğer dosyayı açarsanız aşağıdaki gibi olduğunu göreceksiniz. 99 | 100 | 101 | ```html 102 | 103 | 104 | 105 | 106 | MyFirstApp 107 | 108 | 109 | 110 | 111 | Loading... 112 | 113 | 114 | ``` 115 | 116 | Body etiketinin içinde html standardına uymayan özel bir etiketimiz var, `app-root` elementi. 117 | 118 | Eğer `app` klasörüne göz atarsanız ve `app.component.ts` adlı dosyayı açarsanız aşağıdaki gibi olduğunu göreceksiniz. 119 | 120 | ```ts 121 | import { Component } from '@angular/core'; 122 | 123 | @Component({ 124 | selector: 'app-root', 125 | templateUrl: './app.component.html', 126 | styleUrls: ['./app.component.css'] 127 | }) 128 | export class AppComponent { 129 | } 130 | ``` 131 | 132 | Gördüğünüz gibi 'selector' olarak 'app-root' seçilmiş. Angular komponentleri elementlere `selector` adı verilen seçiciler ile bağlanırlar. Seçiciler bir bir çeşit css element seçicisi gibidir. Eğer `name` yazarsanız bir `etiket` seçmiş olursunuz, `.name` yazarsanız bir `class` seçmiş olursunuz ya da `[name]` yazarsanız bir `property` seçmiş olursunuz. 133 | 134 | `templateUrl` özelliği komponentin arayüz şablonunun konumunu tutar. Bunun yerine `template` özelliğini kullanarak direkt bu dosyaya da html şablon yazabilirsiniz, ihtiyacınıza göre buna siz karar verebilirsiniz. 135 | 136 | ```ts 137 | import { Component } from '@angular/core'; 138 | 139 | @Component({ 140 | selector: 'app-root', 141 | template: ` 142 | hi 143 | `, 144 | styleUrls: ['./app.component.css'] 145 | }) 146 | export class AppComponent { 147 | } 148 | ``` 149 | 150 | `styleUrls` özelliği bize komponentin stil dosyasının konumunu gösterir. Yine yukarıda olduğu gibi `styles` kullanarak da css dosyası kullanmadan direkt olarak bu dosyaya css yazabilirsiniz. Ancak `template` ile `styles` arasında bir fark bulunur, styles bir string dizisi kabul eder, doğrudan string veremezsiniz. 151 | 152 | ```ts 153 | import { Component } from '@angular/core'; 154 | 155 | @Component({ 156 | selector: 'app-root', 157 | template: ` 158 | hi 159 | `, 160 | styles: [ 161 | `b { 162 | color: red; 163 | }` 164 | ] 165 | }) 166 | export class AppComponent { 167 | } 168 | ``` 169 | 170 | `app.component.spec.ts` dosyası testler hakkında işlemler içerir. Şimdilik bunu da erteliyoruz. (Söylemiştim testlerin kaderi bu.) 171 | 172 | Angular projeleri modüller ile çalışır. Bu moduller `java` daki paketlere ya da `c#` daki isim uzaylarına benzerler. Sizin komponentleriniz bir modulde tanımlanır. `app.module.ts` dosyası ana modulu içerir. 173 | 174 | 175 | ```ts 176 | import { BrowserModule } from '@angular/platform-browser'; 177 | import { NgModule } from '@angular/core'; 178 | import { FormsModule } from '@angular/forms'; 179 | import { HttpModule } from '@angular/http'; 180 | 181 | import { AppComponent } from './app.component'; 182 | 183 | @NgModule({ 184 | declarations: [ 185 | AppComponent 186 | ], 187 | imports: [ 188 | BrowserModule, 189 | FormsModule, 190 | HttpModule 191 | ], 192 | providers: [], 193 | bootstrap: [AppComponent] 194 | }) 195 | export class AppModule { } 196 | ``` 197 | 198 | Projede kullanılacak tüm komponentler bu dosyada deklare edilmelidir. Eğer burada deklare etmezsek kullandığımız zaman angular bu komponentleri bulamaz. 199 | 200 | Şu anda diğer dosyaları ayrıntılı olarak açıklamak istemiyorum. Bunlara da sonra geleceğiz. 201 | 202 | > Daha derine gitmeden önce typescript öğrenmenizi tavsiye ediyorum. Eğer konu hakkında bilginiz yoksa bi göz atıp sonra buradan devam edin. 203 | 204 | 205 | ### Yeni bir komponent oluşturmak 206 | 207 | Yeni bir komponent oluştururken; önce `./src/app` dizininde bir `server` adında bir klasör oluşturalım. 208 | Bu klasör içinde de `server.component.ts` adında bir dosya oluşturalım. Ayrıca `server.component.html` adında bir dosya daha oluşturmalısınız. 209 | 210 | server.component.ts içinde; 211 | 212 | ```ts 213 | export class ServerComponent { 214 | 215 | } 216 | ``` 217 | 218 | `ServerComponent` adında bir sınıf oluşturduk ve sınıfı export ettik. Eğer export etmeseydik bu sınıfı dışarıda kullanamazdık. Hala yapmamız gereken işler var. Bu sınıfı bir komponente çevirecek bir `decorator` oluşturmalıyız. Hadi yapalım o zaman? 219 | 220 | ```ts 221 | @Component({ 222 | 223 | }) 224 | export class ServerComponent { 225 | 226 | } 227 | ``` 228 | 229 | Bu şekilde derlenmeyecektir. Bir şey daha dahil etmeliyiz. `Component` dekoratörü `@angular/core` paketi içinde tanımlı. Bu paketi şu şekilde import edebiliriz. 230 | 231 | ```ts 232 | import { Component } from '@angular/core'; 233 | 234 | @Component({ 235 | 236 | }) 237 | export class ServerComponent { 238 | 239 | } 240 | ``` 241 | Artık anguların kullanabileceği bir komponent oluşturmuş durumdayız. Fakat hala geçersiz. Çünkü bir `selector`'e sahip değil. Var olmasına rağmen herhangi bir yerde çağırılmış değil. Bu yüzden ona bir `selector` deklare etmeliyiz. 242 | 243 | ```ts 244 | import { Component } from '@angular/core'; 245 | 246 | @Component({ 247 | selector: 'app-server' 248 | }) 249 | export class ServerComponent { 250 | 251 | } 252 | ``` 253 | 254 | `selector` css seçicisi gibidir. Herhangi bir yere direkt olarak `app-server` yazarsanız; `` şeklinde görünecektir. Eğer `.app-server` şeklinde kullanırsanız `
`. Hatta `[app-server]` bir özellik(property, attribute) olarak bile kullanabilirsiniz. (şöyle `
`). 255 | 256 | Komponentin html dosyasını komponente bağlamalıyız. Bunun için `templateUrl` kullanacağız. Tıpkı `app.component` içinde olduğu gibi. 257 | 258 | ```ts 259 | import {Component} from '@angular/core'; 260 | 261 | @Component({ 262 | selector: 'app-server', 263 | templateUrl: './server.component.html' 264 | }) 265 | export class ServerComponent { 266 | 267 | } 268 | ``` 269 | 270 | Bu komponenti kullanabilmek için `app.module.ts` içinde deklare etmeliyiz. 271 | 272 | 273 | ```ts 274 | import { BrowserModule } from '@angular/platform-browser'; 275 | import { NgModule } from '@angular/core'; 276 | import { FormsModule } from '@angular/forms'; 277 | import { HttpModule } from '@angular/http'; 278 | 279 | import { AppComponent } from './app.component'; 280 | import { ServerComponent } from './server/server.component' // <<-- önce buradan import ediyoruz 281 | 282 | @NgModule({ 283 | declarations: [ 284 | AppComponent, 285 | ServerComponent // <<-- ardından burada deklarasyonumuza ekliyoruz 286 | ], 287 | imports: [ 288 | BrowserModule, 289 | FormsModule, 290 | HttpModule 291 | ], 292 | providers: [], 293 | bootstrap: [AppComponent] 294 | }) 295 | export class AppModule { } 296 | 297 | ``` 298 | 299 | Şimdi `server.component.html` dosyasını değiştireceğim. 300 | 301 | ```html 302 | server component 303 | ``` 304 | 305 | Artık bu komponenti kullanbiliriz. Hemen `app.component.html` içinde kullanalım. 306 | 307 | ```html 308 | app component 309 | 310 | 311 | ``` 312 | 313 | Şimdi [http://localhost:8080](http://localhost:8080) adresine bir göz atalım. 314 | 315 | ![](images/1.png) 316 | 317 | ### Komut satırı ile bir komponent oluşturmak 318 | 319 | Bazen sürekli kendini tekrar eden yapıları üst üste oluşturmak istemeyebiliriz. Bu durum için `@angular/cli`'in bir çözümü var. `ng` nin generate fonksiyonu bize yeni komponentler oluşturmak için yardımcı oluyor. 320 | 321 | ``` 322 | ng generate component 323 | or 324 | ng g c 325 | ``` 326 | 327 | Eğer bir servers adında bir komponent oluşturmak istersek. 328 | 329 | ``` 330 | ng generate component servers 331 | ``` 332 | 333 | `app` dizini içine `servers` klasörü oluşturacak, onun da içine `ts`i `html`, `css` ve `.spec.ts` dosyalarını otomatik oluşturacaktır. Ayrıca `app.module.ts` içine bizim yerimize deklarasyon ekleyecek kısaca komponenti direkt olarak kullanıma hazır hale getirecektir. 334 | 335 | 336 | ### Projeye bootstrap css eklemek 337 | 338 | Projemizde Boostrap'e ihtiyaç duyabiliriz. Nasıl import edeceğiz? İlk olarak indirmek zorundayız. 339 | 340 | ``` 341 | npm install bootstrap --save 342 | ``` 343 | 344 | Ardından `.angular-cli.json` dosyasını açarak şu şekilde düzenlemeliyiz. 345 | 346 | ```js 347 | { 348 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 349 | "project": { 350 | "version": "1.0.0-beta.32.3", 351 | "name": "new-cli" 352 | }, 353 | "apps": [ 354 | { 355 | "root": "src", 356 | "outDir": "dist", 357 | "assets": [ 358 | "assets", 359 | "favicon.ico" 360 | ], 361 | "index": "index.html", 362 | "main": "main.ts", 363 | "polyfills": "polyfills.ts", 364 | "test": "test.ts", 365 | "tsconfig": "tsconfig.json", 366 | "prefix": "app", 367 | "styles": [ 368 | "../node_modules/bootstrap/dist/css/bootstrap.min.css", // <<-- bu satırı ekledik 369 | "styles.css" 370 | ], 371 | "scripts": [], 372 | "environmentSource": "environments/environment.ts", 373 | "environments": { 374 | "dev": "environments/environment.ts", 375 | "prod": "environments/environment.prod.ts" 376 | } 377 | } 378 | ], 379 | "e2e": { 380 | "protractor": { 381 | "config": "./protractor.conf.js" 382 | } 383 | }, 384 | "lint": [ 385 | { 386 | "files": "src/**/*.ts", 387 | "project": "src/tsconfig.json" 388 | }, 389 | { 390 | "files": "e2e/**/*.ts", 391 | "project": "e2e/tsconfig.json" 392 | } 393 | ], 394 | "test": { 395 | "karma": { 396 | "config": "./karma.conf.js" 397 | } 398 | }, 399 | "defaults": { 400 | "styleExt": "css", 401 | "component": {} 402 | } 403 | } 404 | 405 | ``` 406 | 407 | Artık bootstrap kullanıma hazır. 408 | 409 | >**Note:** Bootstrap için bir kütüphane mevcut [bootstrap](https://github.com/ng-bootstrap/ng-bootstrap). Kolayca kullanabileceğimiz bir çok komponent içeriyor. 410 | 411 | 412 | ### Databinding 413 | 414 | Databinding basitçe şablonlar ve sınıflar arasında verilerin bağlanmasını sağlar. 415 | 416 | * **OUT** String Interpolation: Değişkeni şablona bağlar. Yazımı `{{ data }}` şeklindedir. 417 | * **OUT** Property Binding: Bir değişkeni şablonun bir özelliğine atar. Yazımı `[property]="data"` şeklindedir. 418 | * **IN** Olay yakalama: Olayı sınıftaki bir methoda bağlama. Yazımı `(event)="expression"` şeklindedir. 419 | 420 | #### String Interpolation 421 | 422 | Hadi isim yazan basit bir komponent yaratalım. İsim String Interpolation ile bizim sınıfımız içinde tanımlansın. 423 | 424 | ```ts 425 | import { Component } from '@angular/core'; 426 | 427 | @Component({ 428 | selector: 'app-name', 429 | template: ` 430 |

My name is {{name}}

431 | ` 432 | }) 433 | export class NameComponent { 434 | name: string = "Doğan"; 435 | } 436 | ``` 437 | 438 | Sonuç: 439 | 440 | ![](images/2.png) 441 | 442 | 443 | Bu sefer 1 saniyelik bir gecikme ekleyelim. 1 saniyenin ardından ismin Göksel olarak değişeceğini göreceğiz. Ne kadar güzel bir isim. 444 | 445 | ```ts 446 | import { Component } from '@angular/core'; 447 | 448 | @Component({ 449 | selector: 'app-name', 450 | template: ` 451 |

My name is {{name}}

452 | ` 453 | }) 454 | export class NameComponent { 455 | name: string = "Doğan"; 456 | 457 | constructor() { 458 | setTimeout(() => { 459 | this.name = "Göksel"; 460 | }, 1000); 461 | } 462 | } 463 | ``` 464 | 465 | Başlangıçta bize ` My name is Doğan ` yazmasının 1 saniye sonrasında ` My name is Göksel ` yazısını gördük. Databinding şablonu render etti. Yani render konusunu kafanıza takmayın. 466 | 467 | #### Property binding and Event Binding 468 | 469 | Şimdi diğer databinding(veri bağlama) tiplerini de görelim. 470 | 471 | ```ts 472 | import { Component } from '@angular/core'; 473 | 474 | @Component({ 475 | selector: 'app-name', 476 | template: ` 477 | 478 | 479 | ` 480 | }) 481 | export class NameComponent { 482 | isDisabled = true; 483 | 484 | someAction() { 485 | alert("hello"); 486 | } 487 | 488 | changeDisabled() { 489 | this.isDisabled = !this.isDisabled; // değeri ters çevir 490 | } 491 | } 492 | ``` 493 | 494 | Başlangıçta button tıklanamaz durumda. Ancak diğer butona tıkladığımızda artık tıklanabilir duruma geçiyor ve siz butona tıkladığınızda "merhaba" diyen bir alert görüyorsunuz. 495 | 496 | #### Two way databinding 497 | 498 | Angular'da bir databinding tipi daha var. Bu da `Two way databinding` (İki yönlü veri bağlama). Bu sefer olaylar, özellikler ve sınıflar bağlanacak. 499 | 500 | ```ts 501 | import { Component } from '@angular/core'; 502 | 503 | @Component({ 504 | selector: 'app-name', 505 | template: ` 506 | 507 | 508 |

My name is {{name}}

509 | ` 510 | }) 511 | export class NameComponent { 512 | name: string = "Doğan"; 513 | } 514 | ``` 515 | 516 | Göreceksiniz input içindeki name özelliği değiştiğinde ` My name is _____ ` kısmı da otomatik olarak yeniden render edilecek. Eğer sınıftaki name özelliğini değiştirirseniz de input içindeki değer değişecektir. 517 | 518 | > **Note:** `ngModel` `app.module.ts` dosyasında import edilmek zorundadır. Gerekli modülün adı `FormsModule`. 519 | 520 | ### Direktifler 521 | 522 | 3 tip direktif var. 523 | 524 | * Komponentler 525 | * Yapısal Direktifler (bunları `*` yıldız karakteri olarak göreceksiniz) 526 | * Özellik Direktifleri 527 | 528 | Komponentleri artık zaten biliyorsunuz. Hadi yapısal direktiflere geçelim. 529 | 530 | Bu direktifler dom'un tamamını kontrol ederler. Neden diye sorabilirsiniz. 531 | 532 | #### ngIf 533 | 534 | Hadi `*ngIf` örneğine bir göz atalım 535 | 536 | 537 | ```ts 538 | import { Component } from '@angular/core'; 539 | 540 | @Component({ 541 | selector: 'app-name', 542 | template: ` 543 | 544 |

545 | I'm visible now 546 |

547 | ` 548 | }) 549 | export class NameComponent { 550 | visible: boolean = false; 551 | } 552 | ``` 553 | 554 | Bu örnekte biz butona tıkladığımızda bir metin beliriyor. Ancak ilginç olan visible değişkeni false olduğunda p elementi henüz yok. Sadece visible değeri true olduğunda yaratılıyor. Yapısal direktifler var olan domu düzenler ya da yok ederler. 555 | 556 | Ayrıca else de (Angular 4) kullanabilirsiniz. 557 | 558 | 559 | ```ts 560 | import { Component } from '@angular/core'; 561 | 562 | @Component({ 563 | selector: 'app-name', 564 | template: ` 565 | 566 |

567 | I'm visible now 568 |

569 | 570 |

571 | I'm hidden 572 |

573 |
574 | 575 | ` 576 | }) 577 | export class NameComponent { 578 | visible: boolean = false; 579 | } 580 | ``` 581 | 582 | Devam etmeden önce lütfen deneyin. 583 | 584 | #### ngFor 585 | 586 | ngFor da yapısal bir direktifdir. Verilen diziye göre kendini düzenler ve kopyalar. Örneğin; 587 | 588 | ```ts 589 | import { Component } from '@angular/core'; 590 | 591 | @Component({ 592 | selector: 'app-name', 593 | template: ` 594 |
    595 |
  • {{car}}
  • 596 |
597 | ` 598 | }) 599 | export class NameComponent { 600 | cars = [ 601 | 'Toyota', 602 | 'Honda', 603 | 'Ford' 604 | ] 605 | } 606 | ``` 607 | 608 | ![](images/3.png) 609 | 610 | ngFor ayrıca index'e de sahiptir. Eğer `;` bu kapsamda kullanabileceğiniz bir index değişkeni tanımlayabilirsiniz. 611 | 612 | ```ts 613 | import { Component } from '@angular/core'; 614 | 615 | @Component({ 616 | selector: 'app-name', 617 | template: ` 618 |
    619 |
  • ({{i}}) {{car}}
  • 620 |
621 | ` 622 | }) 623 | export class NameComponent { 624 | cars = [ 625 | 'Toyota', 626 | 'Honda', 627 | 'Ford' 628 | ] 629 | } 630 | ``` 631 | 632 | ![](images/4.png) 633 | 634 | 635 | #### ngStyle 636 | 637 | ngStyle bir özellik direktifidir. Yapısal direktifler gibi görünmez. 638 | 639 | ```ts 640 | import { Component } from '@angular/core'; 641 | 642 | @Component({ 643 | selector: 'app-name', 644 | template: ` 645 |
    646 |
  • {{car.name}}
  • 647 |
648 | ` 649 | }) 650 | export class NameComponent { 651 | cars = [ 652 | { 653 | name: 'Toyota', 654 | total: 1 655 | }, 656 | { 657 | name: 'Ford', 658 | total: 0 659 | } 660 | ] 661 | } 662 | ``` 663 | 664 | Toyota elemanının yeşil Ford elemanının kırmızı olduğunu göreceksiniz. 665 | 666 | #### ngClass 667 | 668 | ngClass da özellik direktifidir. 669 | 670 | ```ts 671 | import { Component } from '@angular/core'; 672 | 673 | @Component({ 674 | selector: 'app-name', 675 | template: ` 676 |
    677 |
  • {{car.name}}
  • 678 |
679 | `, 680 | 681 | styles: [ 682 | `.notInStock { 683 | background-color: red 684 | }` 685 | ] 686 | }) 687 | export class NameComponent { 688 | cars = [ 689 | { 690 | name: 'Toyota', 691 | total: 1 692 | }, 693 | { 694 | name: 'Ford', 695 | total: 0 696 | }, 697 | ] 698 | } 699 | ``` 700 | 701 | Toyota elemanının normal ancak Ford elemanının kırmızı göründüğünü göreceksiniz. 702 | 703 | #### ngSwitch 704 | 705 | ngSwitch birden fazla durum arasında geçiş içindir. Çok kullanışlı bir ön tanımlı direktif. 706 | 707 | ```ts 708 | import { Component } from '@angular/core'; 709 | 710 | @Component({ 711 | selector: 'app-name', 712 | template: ` 713 |
714 |

Count is 5

715 |

Count is 10

716 |

Count is Default

717 |
718 | ` 719 | }) 720 | export class NameComponent { 721 | count: number = 5; 722 | } 723 | ``` 724 | 725 | 726 | ### Input 727 | 728 | Bu bölümde hedefimiz bazı özellikleri dışarıdan erişilebilir hale getirmek olacak. Buna neden ihtiyaç duyalım diye sorabilirsiniz. Biz komponentleri kendi kapsamımızda yaratıyoruz. Örneğin "yeni bir kullanıcı yarat" adında bir komponenti ve "kullanıcıları listele" komponenti oluşturalım. Bu komponentler birbirleriyle etkileşime geçmek zorunda. 729 | 730 | Yapmak istediklerimize başlarsak, birkaç komponent oluşturacağız. 731 | 732 | ```bash 733 | ng new my-second-app 734 | cd my-second-app 735 | ng g c users --spec false #-- spec false blocks spec file generation 736 | ng g c users/user-list --spec false # users/list syntax will create a component in users folder. 737 | ng g c users/user-item --spec false 738 | ng g c users/user-create --spec false 739 | ``` 740 | 741 | app.component.html dosyasını bu şekilde 742 | 743 | ```html 744 | 745 | ``` 746 | 747 | 748 | users.component.html dosyasını da bu şekilde düzenleyelim 749 | 750 | ```html 751 | 752 |
753 | 754 | ``` 755 | 756 | ardından komponent dosyamıza bir kullanıcı dizisi ekleyelim. 757 | 758 | ```ts 759 | import { Component, OnInit } from '@angular/core'; 760 | 761 | @Component({ 762 | selector: 'app-user-list', 763 | templateUrl: './user-list.component.html', 764 | styleUrls: ['./user-list.component.css'] 765 | }) 766 | export class UserListComponent implements OnInit { 767 | users = ['Jack', 'George', 'Another common name']; // << bu satır 768 | 769 | constructor() { } 770 | 771 | ngOnInit() { 772 | } 773 | } 774 | ``` 775 | 776 | user-list.component.html komponentini de şu şekilde düzenleyelim. 777 | 778 | ```html 779 | 780 | ``` 781 | 782 | user-item.component.html ve user-item.component.ts dosyalarını da şöyle 783 | 784 | ```html 785 |

786 | User name: {{name}} 787 | 788 | 789 |

790 | ``` 791 | 792 | ```ts 793 | import { Component, OnInit } from '@angular/core'; 794 | 795 | @Component({ 796 | selector: 'app-user-item', 797 | templateUrl: './user-item.component.html', 798 | styleUrls: ['./user-item.component.css'] 799 | }) 800 | export class UserItemComponent implements OnInit { 801 | name: string; 802 | constructor() { } 803 | 804 | ngOnInit() { 805 | } 806 | 807 | } 808 | ``` 809 | 810 | Sonuç olarak artık hazırız. Eğer bu noktaya kadar hatasız geldiyseniz şu ekranı görüyor olmalısınız. 811 | 812 | ![](images/5.png) 813 | 814 | Kullanıcı alanları oluşturuldu fakat isim kısmı tam çalışıyor gibi görünmüyor. Yapmadığımız bir şeyi yapmak zorundayız. UserItemComponent elementinin name özelliği diğer komponent tarafından erişilemez çünkü kendi kapsamıyla sınırlı. Erişim için bir dekoratör eklemek zorundayız. Dekoratörümüzün adı `@Input` 815 | 816 | Şimdi user.component.ts dosyamızı şu şekilde düzenliyoruz 817 | 818 | 819 | ```ts 820 | import { Component, OnInit } from '@angular/core'; 821 | 822 | @Component({ 823 | selector: 'app-user-item', 824 | templateUrl: './user-item.component.html', 825 | styleUrls: ['./user-item.component.css'] 826 | }) 827 | export class UserItemComponent implements OnInit { 828 | @Input() name: string; 829 | constructor() { } 830 | 831 | ngOnInit() { 832 | } 833 | 834 | } 835 | ``` 836 | 837 | `@Input` dekoratörü aslında bir dekoratör oluşturma fonksiyonu. O yüzden onu bir method çağırır gibi çağırıyoruz `@Input()`. İlk parametreye bir isim verebilirsiniz. Bununla ilgili bir örnek de göstereceğim. 838 | 839 | Şimdi uygulamamızı tekrar test ediyoruz ama sonuç değişmiyor. :worried: 840 | 841 | ![](images/5.png) 842 | 843 | Şimdi de name değişkenini set etmeyi unuttuk çünkü ona user-item komponentinin dışından erişimimiz yok. 844 | 845 | Bu kez user-list.component.html dosyasını düzenliyoruz: 846 | 847 | ```html 848 | 849 | ``` 850 | 851 | Gördüğünüz gibi property binding kullandık. Basitçe `@Input` bir özellik olarak çalışıyor. Biz değeri user olarak tanımladık, çünkü değişkeni ngFor içinde `user` olarak tanımlamıştık. 852 | 853 | Şimdi bir kez daha bakalım. 854 | 855 | ![](images/6.png) 856 | 857 | Şimdi de isim vererek `@Input()` kullanımına bir örnek verelim. 858 | 859 | app-user-item.ts 860 | 861 | ```ts 862 | import { Component, OnInit } from '@angular/core'; 863 | 864 | @Component({ 865 | selector: 'app-user-item', 866 | templateUrl: './user-item.component.html', 867 | styleUrls: ['./user-item.component.css'] 868 | }) 869 | export class UserItemComponent implements OnInit { 870 | @Input('user') name: string; // << gördüğünüz gibi bir parametre verdik 871 | constructor() { } 872 | 873 | ngOnInit() { 874 | } 875 | 876 | } 877 | ``` 878 | 879 | Şimdi komponent `user` özelliği arayacak. 880 | 881 | 882 | Tekrar user-list.component.html dosyamızı düzenleyelim: 883 | 884 | ```html 885 | 886 | ``` 887 | 888 | ### Output 889 | 890 | Input'tan bahsedeceğimiz son kısım. Örneğimizde ekleme ve silme butonları eklemiştik. Ayrıca bir user-create komponenti de. Bir göz atalım. 891 | 892 | user-create.component.html 893 | 894 | ```html 895 | name: 896 | 897 | ``` 898 | 899 | user-create.component.ts 900 | 901 | ```ts 902 | import { Component, OnInit, Output, EventEmitter } from '@angular/core'; 903 | 904 | @Component({ 905 | selector: 'app-user-create', 906 | templateUrl: './user-create.component.html', 907 | styleUrls: ['./user-create.component.css'] 908 | }) 909 | export class UserCreateComponent implements OnInit { 910 | 911 | constructor() { } 912 | 913 | ngOnInit() { 914 | } 915 | 916 | name: string; // two-way-binding property 917 | 918 | @Output() 919 | onUserCreated = new EventEmitter(); // bu komponent dışından çağırılabilen bir olayımız 920 | // not: @angular/core modülünden EventEmitter import edilmiş olmalı 921 | 922 | onUserCreate() { // kullanıcı butona tıkladığında bu method tetiklenecek 923 | this.onUserCreated.emit(this.name); // buradan eventEmitter'e veri yollayacağız 924 | } 925 | } 926 | ``` 927 | 928 | > **Not:** Kullanıcıları üst komponente taşıyacağım. 929 | 930 | users.component.html 931 | 932 | ```html 933 | 934 |
935 | 936 | ``` 937 | 938 | users.component.ts 939 | 940 | ```ts 941 | import { Component, OnInit } from '@angular/core'; 942 | 943 | @Component({ 944 | selector: 'app-users', 945 | templateUrl: './users.component.html', 946 | styleUrls: ['./users.component.css'] 947 | }) 948 | export class UsersComponent implements OnInit { 949 | users = ['Jack', 'George', 'Another common name']; 950 | 951 | constructor() { } 952 | 953 | ngOnInit() { 954 | } 955 | 956 | onUserCreated(name) { 957 | this.users.push(name); 958 | } 959 | } 960 | ``` 961 | 962 | user-list.component.ts 963 | 964 | ```ts 965 | import { Component, OnInit, Input } from '@angular/core'; 966 | 967 | @Component({ 968 | selector: 'app-user-list', 969 | templateUrl: './user-list.component.html', 970 | styleUrls: ['./user-list.component.css'] 971 | }) 972 | export class UserListComponent implements OnInit { 973 | @Input() // added this 974 | users; 975 | 976 | constructor() { } 977 | 978 | ngOnInit() { 979 | } 980 | 981 | } 982 | ``` 983 | 984 | Uygulamamıza bir göz atalım. Eğer inputumuza bir isim yazarsak ve ardından create butonuna tıklarsak. :sunglasses: 985 | 986 | ### View Encapsulation 987 | 988 | Komponentlerin css dosyaları o komponente özeldir. Örneğin; 989 | 990 | ```css 991 | b { 992 | color: red; 993 | } 994 | ``` 995 | 996 | Başka bir komponentin b elementi bu css'den etkilenmeyecektir. Ancak bu durumu değiştirmek isteyebilir, bu css dosyasının tüm uygulama içerisinde gerçerli olmasını sağlayabiliriz. Bunun için ViewEncapsulation'u kullanacağız. 997 | 998 | ```ts 999 | import { Component, ViewEncapsulation } from '@angular/core'; 1000 | 1001 | @Component({ 1002 | selector: 'app-some', 1003 | templateUrl: './some.component.html', 1004 | styleUrls: ['./some.component.css'], 1005 | encapsulation: ViewEncapsulation.None 1006 | }) 1007 | export class SomeComponent { 1008 | 1009 | } 1010 | ``` 1011 | 1012 | ### Local reference 1013 | 1014 | Local reference DOM elemanlarını işaretlemek için kullanılır. `*ngIf` gibi yapısal direktiflerin içinde kullanırız. Yazmam gereken bir şey daha var, `@ViewChild` dekoratörü. 1015 | 1016 | Bu dekoratör DOM elementlerine kod içinden erişime müsade eder. Eğer ne yaptığınızı biliyorsanız kullanın ancak aksi halde bu deokratörü kullanmaktan kaçının. 1017 | 1018 | ```ts 1019 | import { Component, ViewChild, ElementRef } from '@angular/core'; 1020 | 1021 | @Component({ 1022 | selector: 'app-some', 1023 | template: ` 1024 |
1025 | 1026 |
1027 | ` 1028 | }) 1029 | export class SomeComponent { 1030 | @ViewChild('localReference') 1031 | localReferenceDiv: ElementRef; 1032 | } 1033 | ``` 1034 | 1035 | 1036 | ### ng-content 1037 | 1038 | ng-content elementlerin içeriklerine erişmemizi sağlayan özel bir direktiftir. Normal şartlarda angular komponentlerin içeriklerini ezer. `Loading...` bu konsept için iyi bir örnektir. Angular `app-root` içine komponenti yerleştirdiği anda Loading metni yok olacaktır. Fakat ya kaybolmasını bunu istemezsek. 1039 | 1040 | Bir örnek göstermeme izin verin; 1041 | 1042 | ```ts 1043 | import { Component } from '@angular/core'; 1044 | 1045 | @Component({ 1046 | selector: 'app-bold', 1047 | template: ` 1048 | 1049 | 1050 | 1051 | ` 1052 | }) 1053 | export class BoldComponent { 1054 | } 1055 | ``` 1056 | 1057 | ```ts 1058 | import { Component } from '@angular/core'; 1059 | 1060 | @Component({ 1061 | selector: 'app-root', 1062 | template: ` 1063 | bu metin kalın yazılacak 1064 | ` 1065 | }) 1066 | export class AppComponent { 1067 | } 1068 | ``` 1069 | 1070 | > **Not:** Son bölümde ViewChild'ı öğrnemiştik. Eğer içeriğin içinde ViewChild kullanmak isterseniz çalışmayacaktır. Bunun yerine `@ContentChild` kullanmak zorundasınız. 1071 | 1072 | ### Komponentlerin Yaşam Döngüsü 1073 | 1074 | Komponentler standart bir yaşam döngüsüne sahiptir. Sahip olduğu tüm methodlar aşağıda. Bunların hepsini kullanabiliriz. 1075 | 1076 | * ngOnChanges: Bir inputun değeri değiştiğinde. 1077 | * ngOnInit: Komponent ilk kez yüklendiğinde 1078 | * ngDoCheck: Her değişiklik algılandığından çağırılır. 1079 | * ngAfterContentInit: İçerik oluşturulduktan (ng-content) sonra çağırılır 1080 | * ngAfterContentChecked: Yansıtılan içerik her kontrol edildiğinde çağırılır 1081 | * ngAfterViewInit: Komponentin viewları ve alt viewları yansıtıldıktan sonra çağırılır 1082 | * ngAfterViewChecked: View ve alt viewları her kontrol edildiğinde çağırılır 1083 | * ngOnDestroy: Komponent yok edilmeden önce çağırılır 1084 | 1085 | ```ts 1086 | import { Component, OnInit, OnChanges, SimpleChanges, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy } from '@angular/core'; 1087 | 1088 | @Component({ 1089 | selector: 'app-some', 1090 | template: ` ` 1091 | }) 1092 | export class SomeComponent implements OnInit, OnChanges, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy { 1093 | 1094 | ngOnChanges(changes: SimpleChanges): void { 1095 | console.log('ngOnChanges', changes); 1096 | } 1097 | 1098 | ngOnInit(): void { 1099 | console.log('ngOnInit'); 1100 | } 1101 | 1102 | ngDoCheck(): void { 1103 | console.log('ngDoCheck'); 1104 | } 1105 | 1106 | ngAfterContentInit(): void { 1107 | console.log('ngAfterContentInit'); 1108 | } 1109 | 1110 | ngAfterContentChecked(): void { 1111 | console.log('ngAfterContentChecked'); 1112 | } 1113 | 1114 | ngAfterViewChecked(): void { 1115 | console.log('ngAfterViewChecked'); 1116 | } 1117 | 1118 | ngAfterViewInit(): void { 1119 | console.log('ngAfterViewInit'); 1120 | } 1121 | 1122 | ngOnDestroy(): void { 1123 | console.log('ngOnDestroy'); 1124 | } 1125 | } 1126 | ``` 1127 | 1128 | 1129 | ### Yeni bir direktif yaratmak 1130 | 1131 | Şimdiye kadar birkaç tane tanımlı direktif gördük. Fakat ya kendimiz yeni bir tane tanımlamak istersek. Bu bölümde buna göz atacağız. 1132 | 1133 | Direktifler tıpkı komponentler gibi tanımlanır. Onları da app.module.ts dosyasına eklemek zorundasınız. Elle de oluşturabilirdik ancak ben @angular/cli kullanacağım. 1134 | 1135 | ``` 1136 | ng generate directive 1137 | or 1138 | ng g d 1139 | ``` 1140 | 1141 | Üzerine gelindiğinde elementleri yeşil yapan green adında bir direktif tanımlayacağım. 1142 | 1143 | ``` 1144 | ng g d green 1145 | ``` 1146 | 1147 | Şimdilik spec.ts dosyalarını yok ediyorum çünkü şu an testlerle ilgilenmiyoruz. Dosyanın adı green.directive.ts olmalı. Direktif dosyaları `.directive.ts` formatında oluşturulur. 1148 | 1149 | ```ts 1150 | import { Directive } from '@angular/core'; 1151 | 1152 | @Directive({ 1153 | selector: '[appGreen]' 1154 | }) 1155 | export class GreenDirective { 1156 | constructor() { } 1157 | } 1158 | ``` 1159 | 1160 | Bu direktif `appGreen` özelliği ile temsil edilecek. Eğer bu direktifi bir elemente özellik olarak eklerseniz çalıştığını göreceksiniz. 1161 | 1162 | #### HostListener 1163 | 1164 | Hover olayında elementi yeşil yapmayı denemiştik yani bir olayı yakalamak zorundayız. 1165 | 1166 | ```ts 1167 | import { Directive, HostListener } from '@angular/core'; 1168 | 1169 | @Directive({ 1170 | selector: '[appGreen]' 1171 | }) 1172 | export class GreenDirective { 1173 | constructor() { } 1174 | 1175 | @HostListener('mouseenter') 1176 | mouseenter() { 1177 | // mouse enters 1178 | } 1179 | 1180 | @HostListener('mouseleave') 1181 | mouseleave() { 1182 | // mouse leaves 1183 | } 1184 | } 1185 | ``` 1186 | 1187 | #### HostBinding 1188 | 1189 | Peki ya renk değişimi? Bunun için de `@HostBinding` i kullanmalıyız. 1190 | 1191 | ```ts 1192 | import { Directive, HostBinding, HostListener } from '@angular/core'; 1193 | 1194 | @Directive({ 1195 | selector: '[appGreen]' 1196 | }) 1197 | export class GreenDirective { 1198 | @HostBinding('style.backgroundColor') backgroundColor: string = 'transparent'; 1199 | 1200 | @HostListener('mouseenter') 1201 | mouseenter() { 1202 | this.backgroundColor = 'green'; 1203 | } 1204 | 1205 | @HostListener('mouseleave') 1206 | mouseleave() { 1207 | this.backgroundColor = 'transparent'; 1208 | } 1209 | } 1210 | ``` 1211 | 1212 | ### Servisler ve bağımlılıkların zerki 1213 | 1214 | Servisler komponentler arası veri taşımak için oldukça kullanışlıdır. Servis oluşturmak için herhangi bir dekoratöre ihtiyaç duymayız. Hadi bir kullanıcı servisi oluşturalım. 1215 | 1216 | Şu şekilde `.service.ts` bir söz dizimi ile oluşturmanızı tavsiye ederim. 1217 | 1218 | Hadi `app` klasörü içine users.service.ts adında bir dosya oluşturalım. 1219 | 1220 | ```ts 1221 | export class UserService { 1222 | users = [ 1223 | {id: 1, name: 'co3moz'}, 1224 | {id: 2, name: 'goxel'} 1225 | {id: 3, name: 'Ilrkhoaktul'} 1226 | ] 1227 | 1228 | getUsers() { 1229 | return this.users; 1230 | } 1231 | 1232 | addUser(user: {id: number, name: string}) { 1233 | this.users.push(user); 1234 | } 1235 | 1236 | removeUser(id: number) { 1237 | this.users.splice(id, 1); 1238 | } 1239 | } 1240 | ``` 1241 | 1242 | Basitçe bazı fonksiyon ve özellikler içeren bir sınıf oluşturduk. 1243 | 1244 | Şimdi bir komponent içinde kullanalım. 1245 | 1246 | ```ts 1247 | import { UserService } from 'user.service'; 1248 | import { Component } from '@angular/core'; 1249 | 1250 | @Component({ 1251 | selector: 'app-user-list', 1252 | template: ` 1253 |

{{ user.name }}

1254 | `, 1255 | providers: [ 1256 | UserService 1257 | ] 1258 | }) 1259 | export class UserListComponent implements OnInit { 1260 | users; 1261 | constructor(private userService: UserService) {} // userService's type must be declared. Otherwise it won't work. 1262 | 1263 | ngOnInit() { 1264 | this.users = this.userService.getUsers(); // pass reference of array to local variable. 1265 | } 1266 | } 1267 | ``` 1268 | 1269 | > **Önemli Not:** Providers(Sağlayıcılar) komponente servis sağlarlar ancak userlistComponent her oluşturulduğunda kendi UserService servisini oluşturur. Çünkü biz komponente yapıcı fonksiyon içinde her oluşturulduğunda bir UserService oluşturmasını söyledik. Fakat ya bunun uygulama çapında olmasını isteseydik. Bu verileri komponent dışında da kullanmaya ihtiyaç duyabiliriz. Bu iş için app.module.ts dosyasını kullanacağız. Bu dosyanın içindeki providers alanına servisimizi ekleyeceğiz. 1270 | 1271 | > **Önemli Not 2:** Eğer yeni bir UserService sağlayıcıs deklare edilmezse userListComponent'in alt komponentleri aynı servisi kullanabilir. Yani komponentin sağlayıcılar kısmı sadece yeni bir sağlayıcı yaratmak için kullanılmalıdır. 1272 | 1273 | Ayrıca `@angular/cli`'i de servis oluşturmak için kullanabilirsiniz 1274 | 1275 | ``` 1276 | ng generate service 1277 | or 1278 | ng g s 1279 | ``` 1280 | 1281 | #### Bir servisi diğer servis içine çağırmak 1282 | 1283 | Bir servise bir başka servisin içinde ihtiyaç duyabiliriz. Örneğin bir loglama servisimiz vardır ve diğer servislerden çağırılması gerekiyordur. Peki bu servisi diğerlerinin içinde nasıl kullanabiliriz? 1284 | 1285 | İşte gidiyoruz, `@Injectable` örnekleri; 1286 | 1287 | ```ts 1288 | import { LoggingService } from 'logging.service'; 1289 | import { Injectable } from '@angular/core'; 1290 | 1291 | @Injectable() 1292 | export class UserService { 1293 | users = [ 1294 | {id: 1, name: 'co3moz'}, 1295 | {id: 2, name: 'goxel'} 1296 | {id: 3, name: 'Ilrkhoaktul'} 1297 | ]; 1298 | 1299 | constructor(private loggingService: LoggingService) { 1300 | 1301 | } 1302 | 1303 | getUsers() { 1304 | return this.users; 1305 | } 1306 | 1307 | addUser(user: {id: number, name: string}) { 1308 | this.users.push(user); 1309 | this.loggingService.log('user added'); 1310 | } 1311 | 1312 | removeUser(id: number) { 1313 | this.users.splice(id, 1); 1314 | this.loggingService.log('user removed'); 1315 | } 1316 | } 1317 | ``` 1318 | 1319 | 1320 | #### Event emitting servisi 1321 | 1322 | Bazı bilgileri yayınlayan olaylara ihtiyaç duyabiliriz. 1323 | 1324 | 1325 | ```ts 1326 | import { LoggingService } from 'logging.service'; 1327 | import { Injectable, EventEmitter } from '@angular/core'; 1328 | 1329 | @Injectable() 1330 | export class UserService { 1331 | users = [ 1332 | {id: 1, name: 'co3moz'}, 1333 | {id: 2, name: 'goxel'} 1334 | {id: 3, name: 'Ilrkhoaktul'} 1335 | ]; 1336 | 1337 | constructor(private loggingService: LoggingService) { 1338 | 1339 | } 1340 | 1341 | userCreated = new EventEmitter<{id: number, name: string}>(); 1342 | 1343 | getUsers() { 1344 | return this.users; 1345 | } 1346 | 1347 | addUser(user: {id: number, name: string}) { 1348 | this.users.push(user); 1349 | this.userCreated.emit(user); 1350 | this.loggingService.log('user added'); 1351 | } 1352 | 1353 | removeUser(id: number) { 1354 | this.users.splice(id, 1); 1355 | this.loggingService.log('user removed'); 1356 | } 1357 | } 1358 | ``` 1359 | 1360 | Komponent içinde sadece bu olaya abone olalım. Daha iyi bir özellik öğreneceğiz ancak bu özelliği de bilmiş olalım. 1361 | 1362 | ```ts 1363 | import { UserService } from 'user.service'; 1364 | import { Component } from '@angular/core'; 1365 | 1366 | @Component({ 1367 | selector: 'app-user-list', 1368 | template: ` 1369 |

{{ user.name }}

1370 | `, 1371 | providers: [ 1372 | UserService 1373 | ] 1374 | }) 1375 | export class UserListComponent implements OnInit { 1376 | users; 1377 | constructor(private userService: UserService) { 1378 | this.userService.userCreated.subscribe((user) => { 1379 | console.log('new user just created'); 1380 | }); 1381 | } // userService's type must be declared. Otherwise it won't work. 1382 | 1383 | ngOnInit() { 1384 | this.users = this.userService.getUsers(); // pass reference of array to local variable. 1385 | } 1386 | } 1387 | ``` 1388 | 1389 | > **Önemli Not:** Bir olaya manuel olarak abone olduğunuz zaman, komponent yok olurken `ngOnDestroy` içinde abonelikten çıkmayı unutmayın. 1390 | 1391 | 1392 | ### Router 1393 | 1394 | Router komponentleri birer sayfaya yönlendirir. Router ilk önce `app.module.ts`'a gider. 1395 | 1396 | Öncelikle `@angular/router` modülünden Routes objesini import etmeliyiz 1397 | 1398 | ```ts 1399 | import { Routes, RouterModule } from '@angular/router'; 1400 | ``` 1401 | 1402 | Ardından bu obje ile bir dizi tanımlayacağız: 1403 | 1404 | ```ts 1405 | const appRoutes: Routes = [ 1406 | { path: 'users', component: UsersComponent} 1407 | ]; 1408 | ``` 1409 | 1410 | `path` tarayıcıdaki rotayı tanımlar, örneğin `users` pathi `/users` adresini tanımlar. Eğer path kısmı boş verildiyse ana sayfa olarak kullanılabilir. 1411 | 1412 | ```ts 1413 | const appRoutes: Routes = [ 1414 | { path: '', component: HomeComponent}, 1415 | { path: 'users', component: UsersComponent} 1416 | ]; 1417 | ``` 1418 | Ardından bu nesneyi `RouterModule.forRoot(appRoutes)` modülüne parametre olarak geçmeliyiz. 1419 | 1420 | > **Not** `app.route.ts` ya da `app.routing.ts` adından dosyalar yaratabilirsiniz. Sizin kararınıza kalmış. 1421 | 1422 | Şimdi routerın komponentleri nerede göstereceğini tanımlayacağız. ``. 1423 | 1424 | Bu componenti app.component.html içine ekliyoruz. 1425 | 1426 | #### Linkler 1427 | 1428 | Bu bölümde router linklerini öğreneceğiz. 1429 | 1430 | Normalde basitçe `href` kullanırız. 1431 | 1432 | ```html 1433 | Home 1434 | ``` 1435 | Ancak angularda bu geçersiz çünkü tıklamalar tam sayfa yenilenmesine neden olur. Uygulamamız mümkün olduğunda kararlı olmak zorunda. 1436 | 1437 | Biz `routerLink` direktifini kullanacağız. 1438 | 1439 | ```html 1440 | Home 1441 | ``` 1442 | 1443 | Bu şekilde `[]` de kullanabilirsiniz. 1444 | 1445 | ```html 1446 | Home 1447 | ``` 1448 | 1449 | #### Active route 1450 | 1451 | Bazen aktif sayfaya özel bir stil vermek ya da başka bir şey yapmak isteyebiliriz. Bunu başarmak için `routerLinkActive` kullanırız. 1452 | 1453 | ```html 1454 |
1455 | Home 1456 |
1457 | ``` 1458 | 1459 | routerLinkActive direktifi `routerLinkActiveOptions` adında başka bir direktife sahiptir. Bu routerLinkActiveOptions direktifiyle birlikte ek opsiyonlar verebiliriz. Örneğin tam path doğrulaması: 1460 | 1461 | ```html 1462 |
1463 | Home 1464 |
1465 | ``` 1466 | 1467 | #### Navigating from code 1468 | 1469 | Bazen router'a kod içinden erişmek çok kullanışlı olabilir. 1470 | 1471 | ```ts 1472 | import { Component } from '@angular/core'; 1473 | import { Router } from '@angular/router'; 1474 | 1475 | @Component({ 1476 | selector: 'app-user-list', 1477 | template: `` 1478 | }) 1479 | export class UserListComponent { 1480 | constructor(private router: Router) { 1481 | } 1482 | 1483 | navigateSomewhereElse() { 1484 | this.router.navigate(['/home']); 1485 | } 1486 | 1487 | } 1488 | ``` 1489 | 1490 | 1491 | #### Parameters of routes 1492 | 1493 | Örnekler her şeyi gösteriyor. 1494 | 1495 | ```ts 1496 | const appRoutes: Routes = [ 1497 | { path: '', component: HomeComponent}, 1498 | { path: 'users/:id', component: UsersComponent} 1499 | ]; 1500 | ``` 1501 | 1502 | ```ts 1503 | import { Component } from '@angular/core'; 1504 | import { ActivatedRoute } from '@angular/router'; 1505 | 1506 | @Component({ 1507 | selector: 'app-user-list', 1508 | template: `` 1509 | }) 1510 | export class UsersComponent { 1511 | constructor(private route: ActivatedRoute) { 1512 | } 1513 | 1514 | getIdParameter() { 1515 | return this.route.snapshot.params['id']; 1516 | } 1517 | 1518 | } 1519 | ``` 1520 | 1521 | #### Nested routes 1522 | 1523 | Birleşik rotalar birden fazla komponenti aynı anda göstermek istediğimiz zaman kullanışlı olabilir. 1524 | 1525 | ```ts 1526 | const appRoutes: Routes = [ 1527 | { path: '', component: HomeComponent }, 1528 | { path: 'users', component: UsersComponent, children: [ 1529 | { path: ':id', component: UserComponent }, 1530 | { path: ':id/edit', component: UserEditComponent } 1531 | ]} 1532 | ]; 1533 | ``` 1534 | 1535 | Ana komponente `` eklemeyi unutmayın. 1536 | 1537 | 1538 | #### Redirecting 1539 | 1540 | Bazen bir route'u yönlendirme isteyebiliriz. Basitçe redirectTo parametresiyle bunu gerçekleştirebiliriz. Örneğin; 1541 | 1542 | ```ts 1543 | const appRoutes: Routes = [ 1544 | { path: '', component: HomeComponent }, 1545 | { path: 'users', component: UsersComponent }, 1546 | { path: 'people', redirectTo: '/users' } 1547 | ]; 1548 | ``` 1549 | 1550 | Bu özellikle wildcard özelliği ve 404 sayfaları yapabilirz. 1551 | 1552 | ```ts 1553 | const appRoutes: Routes = [ 1554 | { path: '', component: HomeComponent }, 1555 | { path: 'users', component: UsersComponent }, 1556 | { path: 'not-found', component: NotFoundComponent }, 1557 | { path: '**', redirectTo: '/not-found' } // make sure wildcard is at the end. 1558 | ]; 1559 | ``` 1560 | 1561 | Diğer tüm karşılıksız adresler `NotFoundComponent` komponentine gidecektir. 1562 | --------------------------------------------------------------------------------