背景
最近在Taptap上下载一个游戏,叫盗墓长生印,非常有意思,里面有一个小游戏,叫八宝盒,类似于华容道,打算开发一个网页版的自动完成,既然最近在学Angular4.0.0,那就拿Angular4.0开发把。算法我打算用DFS,用Typescript写算法不知道好不好写,二维数组就不怎么好定义。等完成后会放到github上。
网上查了好多,父子组件通讯比较简单,但是兄弟组件通讯只能用service,如果有更好的方法欢迎留言交流。
附一张八宝盒的截图

项目结构

说明
Main这个组件主要是背景面板,执行DFS算法等。
FooterButton这个组件主要是有开始、重置、上一步、下一步按钮,并且点击八宝盒的滑块可以添加一个八宝盒到Main组件的面板上。
问题
如何再单击FooterButton滑块后,告诉Main组件我要添加1号滑块?
解决方法
创建一个Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| //add-ba-bao-he.service.ts 这是兄弟组件通信的桥梁 import { Injectable } from '@angular/core'; import { Subject } from 'rxjs/Subject';
@Injectable() export class AddBaBaoHeService { private caseNumber = new Subject<number>();
// Observable string streams caseNumber$ = this.caseNumber.asObservable();
// Service message commands publishData(data: number) { this.caseNumber.next(data); }
} //其实还不太懂Subject呢,等有时间再细琢磨下
|
然后就是调用这个服务了
首先是FooterButton调用这个服务,传一个Number类型的值进去。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| //footerbutton.component.ts FooterButton组件 import { Component, EventEmitter , Input , Output } from '@angular/core'; import {AddBaBaoHeService} from '../add-ba-bao-he.service'; @Component({ selector: 'app-footerbutton', templateUrl: './footerbutton.component.html', styleUrls: ['./footerbutton.component.css'],
}) export class FooterbuttonComponent{ constructor(private _AddBaBaoHeService : AddBaBaoHeService) { this._AddBaBaoHeService.caseNumber$.subscribe( data => { console.log('Sibling1Component-received from sibling2: ' + data); }); } //添加滑块的事件 请看楼下的html代码 add(type:number){ this._AddBaBaoHeService.publishData(type); } ngOnInit() { }
}
//footerbutton.component.html <div class="img_div"> <img src="../../assets/images/block_sh.jpg" (click)="add(1)" alt="" class="img"> <img src="../../assets/images/block_sv.jpg" (click)="add(2)" alt="" class="img"> <img src="../../assets/images/block_bh.jpg" (click)="add(3)" alt="" class="img"> <img src="../../assets/images/block_bv.jpg" (click)="add(4)" alt="" class="img"> <img src="../../assets/images/block_open.jpg" (click)="add(5)" alt="" class="img"> </div> <div class="button_div"> <button>开始</button> <button>重置</button> <button>上一步</button> <button>下一步</button> </div>
|
然后是Main组件接收这个service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| //main.component.ts Main组件 import { Component, OnInit ,Input , OnChanges , SimpleChanges} from '@angular/core'; import {AddBaBaoHeService} from '../add-ba-bao-he.service';
@Component({ selector: 'app-main', templateUrl: './main.component.html', styleUrls: ['./main.component.css'], }) export class MainComponent implements OnChanges { //地图 map : number[][]=[[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]]; imghtml : string = ''; constructor(private _AddBaBaoHeService : AddBaBaoHeService) { this._AddBaBaoHeService.caseNumber$.subscribe( data => { console.log("滑块是"+data+"号"); }); } ngOnInit(){
console.log(this.map); } //我咋觉得这个函数都进不去呢,不知道是为啥,为什么写这个方法下面解释 ngOnChanges(changes:SimpleChanges) { console.log("changed"); //console.log(this._AddBaBaoHeService.subscribeData()); //this.sibling2Form.get('caseNumber').value=this._sharedService.subscribeData(); //this.searchCaseNumber = this._sharedService.subscribeData(); //console.log('Sibling2Component-received from sibling1: ' + this.searchCaseNumber); }
}
|
最后要在app.module.ts里面 加上AddBaBaoHeService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| //app.module.ts import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component'; import { FooterbuttonComponent } from './footerbutton/footerbutton.component'; import { MainComponent } from './main/main.component'; import {AddBaBaoHeService} from './add-ba-bao-he.service';
@NgModule({ declarations: [ AppComponent, FooterbuttonComponent, MainComponent ], imports: [ BrowserModule, FormsModule, HttpModule ], providers: [AddBaBaoHeService], bootstrap: [AppComponent] }) export class AppModule { }
|
运行结果
点击第一个滑块后,Chrome的控制台截图如下

疑惑
main组件里面有个ngOnChanges方法,我觉得并没有执行。这段代码我是从plunker粘过来的,还以为要在ngOnchanges这个函数里面处理逻辑了,原作者的意图好像确实是这样,但不知道为什么就是不执行,Angular4的原理还不太名白,所以暂且放着。
结论
完成两个子组件Main和FooterButton的通讯。
附参考的plunker
Angular2 - Communication between component siblings via a service
网页版八宝盒(图片是从这个网页上扒的)