Commit 522b64d0264b88452835c48a16cda08e7f0ea683
1 parent
4fc21097
Exists in
master
ทำให้ parent component (wizard-base) เปลี่ยนข้อมูลตาม child component + reload p…
…arent เมื่อคลิกปุ่ม close (x)
Showing
15 changed files
with
167 additions
and
14 deletions
Show diff stats
src/app/app-routing.module.ts
| ... | ... | @@ -4,6 +4,7 @@ import { RouterModule, Routes } from '@angular/router'; |
| 4 | 4 | import { WizardBaseComponent } from './wizard-base/wizard-base.component'; |
| 5 | 5 | import { ModalOneComponent } from './wizard-base/modal-one/modal-one.component'; |
| 6 | 6 | import { ModalTwoComponent } from './wizard-base/modal-two/modal-two.component'; |
| 7 | +import { DummyComponent } from './dummy/dummy.component'; | |
| 7 | 8 | |
| 8 | 9 | const routes: Routes = [ |
| 9 | 10 | { |
| ... | ... | @@ -14,6 +15,10 @@ const routes: Routes = [ |
| 14 | 15 | { path: '2', component: ModalTwoComponent }, |
| 15 | 16 | ] |
| 16 | 17 | }, |
| 18 | + { | |
| 19 | + path: 'dummy', | |
| 20 | + component: DummyComponent | |
| 21 | + }, | |
| 17 | 22 | { path: '', redirectTo: '/wizard', pathMatch: 'full' }, |
| 18 | 23 | ]; |
| 19 | 24 | ... | ... |
src/app/app.module.ts
| ... | ... | @@ -9,13 +9,16 @@ import { AppComponent } from './app.component'; |
| 9 | 9 | import { WizardBaseComponent } from './wizard-base/wizard-base.component'; |
| 10 | 10 | import { ModalOneComponent } from './wizard-base/modal-one/modal-one.component'; |
| 11 | 11 | import { ModalTwoComponent } from './wizard-base/modal-two/modal-two.component'; |
| 12 | +import { SharedServiceService } from './services/shared-service.service'; | |
| 13 | +import { DummyComponent } from './dummy/dummy.component'; | |
| 12 | 14 | |
| 13 | 15 | @NgModule({ |
| 14 | 16 | declarations: [ |
| 15 | 17 | AppComponent, |
| 16 | 18 | WizardBaseComponent, |
| 17 | 19 | ModalOneComponent, |
| 18 | - ModalTwoComponent | |
| 20 | + ModalTwoComponent, | |
| 21 | + DummyComponent | |
| 19 | 22 | ], |
| 20 | 23 | imports: [ |
| 21 | 24 | BrowserModule, |
| ... | ... | @@ -23,7 +26,7 @@ import { ModalTwoComponent } from './wizard-base/modal-two/modal-two.component'; |
| 23 | 26 | HttpModule, |
| 24 | 27 | AppRoutingModule |
| 25 | 28 | ], |
| 26 | - providers: [], | |
| 29 | + providers: [ SharedServiceService ], | |
| 27 | 30 | bootstrap: [AppComponent] |
| 28 | 31 | }) |
| 29 | 32 | export class AppModule { } | ... | ... |
| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | |
| 2 | + | |
| 3 | +import { DummyComponent } from './dummy.component'; | |
| 4 | + | |
| 5 | +describe('DummyComponent', () => { | |
| 6 | + let component: DummyComponent; | |
| 7 | + let fixture: ComponentFixture<DummyComponent>; | |
| 8 | + | |
| 9 | + beforeEach(async(() => { | |
| 10 | + TestBed.configureTestingModule({ | |
| 11 | + declarations: [ DummyComponent ] | |
| 12 | + }) | |
| 13 | + .compileComponents(); | |
| 14 | + })); | |
| 15 | + | |
| 16 | + beforeEach(() => { | |
| 17 | + fixture = TestBed.createComponent(DummyComponent); | |
| 18 | + component = fixture.componentInstance; | |
| 19 | + fixture.detectChanges(); | |
| 20 | + }); | |
| 21 | + | |
| 22 | + it('should create', () => { | |
| 23 | + expect(component).toBeTruthy(); | |
| 24 | + }); | |
| 25 | +}); | ... | ... |
| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | +import { Component, OnInit } from '@angular/core'; | |
| 2 | + | |
| 3 | +@Component({ | |
| 4 | + selector: 'app-dummy', | |
| 5 | + templateUrl: './dummy.component.html', | |
| 6 | + styleUrls: ['./dummy.component.css'] | |
| 7 | +}) | |
| 8 | +export class DummyComponent implements OnInit { | |
| 9 | + | |
| 10 | + constructor() { } | |
| 11 | + | |
| 12 | + ngOnInit() { | |
| 13 | + console.log('dummy loaded'); | |
| 14 | + } | |
| 15 | + | |
| 16 | +} | ... | ... |
| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | +import { TestBed, inject } from '@angular/core/testing'; | |
| 2 | + | |
| 3 | +import { SharedServiceService } from './shared-service.service'; | |
| 4 | + | |
| 5 | +describe('SharedServiceService', () => { | |
| 6 | + beforeEach(() => { | |
| 7 | + TestBed.configureTestingModule({ | |
| 8 | + providers: [SharedServiceService] | |
| 9 | + }); | |
| 10 | + }); | |
| 11 | + | |
| 12 | + it('should ...', inject([SharedServiceService], (service: SharedServiceService) => { | |
| 13 | + expect(service).toBeTruthy(); | |
| 14 | + })); | |
| 15 | +}); | ... | ... |
| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | +import { Injectable } from '@angular/core'; | |
| 2 | +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; | |
| 3 | + | |
| 4 | +@Injectable() | |
| 5 | +export class SharedServiceService { | |
| 6 | + | |
| 7 | + // title = new Subject<string>(); | |
| 8 | + title = new BehaviorSubject<string>('default'); | |
| 9 | + title$ = this.title.asObservable(); | |
| 10 | + | |
| 11 | + constructor() { | |
| 12 | + } | |
| 13 | + | |
| 14 | + changedTitle(newTitle: string) { | |
| 15 | + this.title.next(newTitle); | |
| 16 | + } | |
| 17 | + | |
| 18 | + | |
| 19 | +} | ... | ... |
src/app/wizard-base/modal-one/modal-one.component.html
| ... | ... | @@ -3,16 +3,17 @@ |
| 3 | 3 | <!-- Modal content --> |
| 4 | 4 | <div class="modal-content"> |
| 5 | 5 | <div class="modal-header"> |
| 6 | - <span class="close">×</span> | |
| 7 | - <h2>Modal Header One</h2> | |
| 6 | + <span class="close" (click)="btnClose()">×</span> | |
| 7 | + <h2>Modal Header One: {{title}}</h2> | |
| 8 | 8 | </div> |
| 9 | 9 | <div class="modal-body"> |
| 10 | 10 | <p>Some text in the Modal Body</p> |
| 11 | 11 | <p>Some other text...</p> |
| 12 | + <button (click)="btnChange()">Change</button> | |
| 12 | 13 | </div> |
| 13 | 14 | <div class="modal-footer"> |
| 14 | 15 | <h3>Modal Footer</h3> |
| 15 | - <button [routerLink]="['/wizard', 2]">Next</button> | |
| 16 | + <button (click)="btnNext()">Next</button> | |
| 16 | 17 | </div> |
| 17 | 18 | </div> |
| 18 | 19 | ... | ... |
src/app/wizard-base/modal-one/modal-one.component.ts
| 1 | -import { Component, OnInit } from '@angular/core'; | |
| 1 | +import { Component, OnDestroy, OnInit } from '@angular/core'; | |
| 2 | +import { SharedServiceService } from '../../services/shared-service.service'; | |
| 3 | +import { Router } from '@angular/router'; | |
| 4 | +import { Subscription } from 'rxjs/Subscription'; | |
| 2 | 5 | |
| 3 | 6 | @Component({ |
| 4 | 7 | selector: 'app-modal-one', |
| 5 | 8 | templateUrl: './modal-one.component.html', |
| 6 | 9 | styleUrls: ['./modal-one.component.css'] |
| 7 | 10 | }) |
| 8 | -export class ModalOneComponent implements OnInit { | |
| 11 | +export class ModalOneComponent implements OnInit, OnDestroy { | |
| 9 | 12 | |
| 10 | - constructor() { } | |
| 13 | + title: string; | |
| 14 | + subscription: Subscription; | |
| 15 | + | |
| 16 | + constructor(private shared: SharedServiceService, private router: Router) { | |
| 17 | + this.subscription = shared.title$.subscribe(title => { | |
| 18 | + this.title = title; | |
| 19 | + }); | |
| 20 | + } | |
| 11 | 21 | |
| 12 | 22 | ngOnInit() { |
| 23 | + | |
| 24 | + } | |
| 25 | + | |
| 26 | + btnChange() { | |
| 27 | + this.shared.changedTitle('modal-one'); | |
| 13 | 28 | } |
| 14 | 29 | |
| 30 | + btnNext() { | |
| 31 | + this.router.navigate(['/wizard', 2]); | |
| 32 | + } | |
| 33 | + | |
| 34 | + btnClose() { | |
| 35 | + this.router.navigate(['/wizard']); | |
| 36 | + } | |
| 37 | + | |
| 38 | + ngOnDestroy() { | |
| 39 | + this.subscription.unsubscribe(); | |
| 40 | + } | |
| 15 | 41 | } | ... | ... |
src/app/wizard-base/modal-two/modal-two.component.html
| ... | ... | @@ -3,16 +3,17 @@ |
| 3 | 3 | <!-- Modal content --> |
| 4 | 4 | <div class="modal-content"> |
| 5 | 5 | <div class="modal-header"> |
| 6 | - <span class="close">×</span> | |
| 7 | - <h2>Modal Header Two</h2> | |
| 6 | + <span class="close" (click)="btnClose()">×</span> | |
| 7 | + <h2>Modal Header Two: {{title}}</h2> | |
| 8 | 8 | </div> |
| 9 | 9 | <div class="modal-body"> |
| 10 | 10 | <p>Some text in the Modal Body</p> |
| 11 | 11 | <p>Some other text...</p> |
| 12 | + <button (click)="btnChange()">Change</button> | |
| 12 | 13 | </div> |
| 13 | 14 | <div class="modal-footer"> |
| 14 | 15 | <h3>Modal Footer</h3> |
| 15 | - <button [routerLink]="['/wizard', 1]">Prev</button> | |
| 16 | + <button (click)="btnPrev()">Prev</button> | |
| 16 | 17 | </div> |
| 17 | 18 | </div> |
| 18 | 19 | ... | ... |
src/app/wizard-base/modal-two/modal-two.component.ts
| 1 | 1 | import { Component, OnInit } from '@angular/core'; |
| 2 | +import { SharedServiceService } from '../../services/shared-service.service'; | |
| 3 | +import { Router } from '@angular/router'; | |
| 2 | 4 | |
| 3 | 5 | @Component({ |
| 4 | 6 | selector: 'app-modal-two', |
| ... | ... | @@ -7,9 +9,30 @@ import { Component, OnInit } from '@angular/core'; |
| 7 | 9 | }) |
| 8 | 10 | export class ModalTwoComponent implements OnInit { |
| 9 | 11 | |
| 10 | - constructor() { } | |
| 12 | + title: string; | |
| 13 | + | |
| 14 | + constructor(private shared: SharedServiceService, private router: Router) { | |
| 15 | + shared.title$.subscribe(title => { | |
| 16 | + this.title = title; | |
| 17 | + }); | |
| 18 | + } | |
| 11 | 19 | |
| 12 | 20 | ngOnInit() { |
| 21 | + | |
| 22 | + } | |
| 23 | + | |
| 24 | + btnChange() { | |
| 25 | + this.shared.changedTitle('modal-two'); | |
| 26 | + } | |
| 27 | + | |
| 28 | + btnPrev() { | |
| 29 | + this.router.navigate(['/wizard', 1]); | |
| 13 | 30 | } |
| 14 | 31 | |
| 32 | + btnClose() { | |
| 33 | + this.router.navigateByUrl('/dummy').then(() => { | |
| 34 | + this.router.navigateByUrl('/wizard'); | |
| 35 | + }); | |
| 36 | + // this.shared.changedTitle('wizard'); | |
| 37 | + } | |
| 15 | 38 | } | ... | ... |
src/app/wizard-base/wizard-base.component.html
src/app/wizard-base/wizard-base.component.ts
| 1 | 1 | import { Component, OnInit } from '@angular/core'; |
| 2 | +import { SharedServiceService } from '../services/shared-service.service'; | |
| 3 | +import { ActivatedRoute, Router } from '@angular/router'; | |
| 4 | + | |
| 2 | 5 | |
| 3 | 6 | @Component({ |
| 4 | 7 | selector: 'app-wizard-base', |
| ... | ... | @@ -6,10 +9,22 @@ import { Component, OnInit } from '@angular/core'; |
| 6 | 9 | styleUrls: ['./wizard-base.component.css'] |
| 7 | 10 | }) |
| 8 | 11 | export class WizardBaseComponent implements OnInit { |
| 12 | + title: string; | |
| 9 | 13 | |
| 10 | - constructor() { } | |
| 14 | + constructor(private shared: SharedServiceService, private router: Router, private route: ActivatedRoute) { | |
| 15 | + shared.title$.subscribe(title => { | |
| 16 | + this.title = title; | |
| 17 | + }); | |
| 18 | + shared.changedTitle('wizard'); | |
| 19 | + } | |
| 11 | 20 | |
| 12 | 21 | ngOnInit() { |
| 22 | + this.route.params.subscribe(params => { | |
| 23 | + console.log('wizard loaded'); | |
| 24 | + }); | |
| 13 | 25 | } |
| 14 | 26 | |
| 27 | + openModal() { | |
| 28 | + this.router.navigate(['/wizard', 1]); | |
| 29 | + } | |
| 15 | 30 | } | ... | ... |
src/index.html