省市區(qū)三級(jí)聯(lián)動(dòng)組件 material angular2

前言

最近在寫(xiě)一個(gè)項(xiàng)目,其中用到省市區(qū)的三級(jí)聯(lián)動(dòng)組件。起初,由于時(shí)間緊湊,使用的是第三方的一個(gè)聯(lián)動(dòng)組件。但是,回過(guò)頭來(lái)發(fā)現(xiàn),整個(gè)組件的風(fēng)格與整個(gè)網(wǎng)站的material風(fēng)格不相符合,心里難受,就自己動(dòng)手寫(xiě)了這么一個(gè)組件,該組件是建立在Google的angular material2的基礎(chǔ)之上進(jìn)行編寫(xiě)的,下面我將記錄編寫(xiě)的整個(gè)流程。

組件效果圖

效果圖

組件分析

1.需要配置@angular/material,配置的問(wèn)題本文不做具體的講述,可以訪問(wèn)下面的鏈接進(jìn)行配置點(diǎn)擊此處(需要翻X)
組件會(huì)使用到angular material中的MdSelectModule,所以需要導(dǎo)入MdSelectModule

2.省市區(qū)數(shù)據(jù)的來(lái)源,其實(shí)網(wǎng)上有許多json的數(shù)據(jù)源,而且這些數(shù)據(jù)源大致都是雷同的,所以我就直接從網(wǎng)上扒下一組比較好處理的json數(shù)據(jù)源,數(shù)據(jù)源放在我的服務(wù)器上數(shù)據(jù)源(直接訪問(wèn)的話,可能瀏覽器編碼需要改一下,也可以直接去瀏覽器后臺(tái)抓取文件)

3.數(shù)據(jù)搞定之后,就來(lái)看一下組件的代碼部分

  • three-link.service.ts代碼部分
import {Injectable} from '@angular/core';
import {Http, Response} from '@angular/http';
import {Observable} from 'rxjs/Rx';

const ThreeLinkUrl = 'src/mock-data/three-link.json';
@Injectable()
export class ThreeLinkService {
  constructor(public _http: Http) {
  }

  public setAll() {           //獲取json中的數(shù)據(jù)
    return this._http.get(ThreeLinkUrl)
      .map((response: Response) => {
          const res = response.json();
          return res;
      })
      .catch((error: any) => Observable.throw('Server error' || error));
  }
}

這里我請(qǐng)求了存放在mock-data文件夾中的three-link.json文件,使用的是rxjs的方法。之后的component中將調(diào)用服務(wù)的setAll()函數(shù)

  • three-link.component.ts代碼部分
mport {Component, OnInit} from  '@angular/core';
import {ThreeLinkService} from './three-link.service';

@Component({
  selector: 'app-three-link',
  templateUrl: './three-link.html',
  styleUrls: ['./three-link.css']
})
export class ThreeLinkComponent implements OnInit {
  public all: Array<object>;                         //存儲(chǔ)所有的省市區(qū)數(shù)據(jù)
  public provinces: Array<object>;                    //存儲(chǔ)省的信息
  public citys: Array<object>;                       //存儲(chǔ)城市的信息
  public areas: Array<object>;                         //存儲(chǔ)地區(qū)的信息
  public cityValue: string;                               //重置城市選擇器時(shí)用到的變量
  public areaValue: string;                            //重置地區(qū)選擇器時(shí)用到的變量
  constructor(public threeLinkService: ThreeLinkService) {

  }
  ngOnInit() {
    this.setAll();
  }

  private setAll() {
    this.threeLinkService.setAll()
      .subscribe(
        data => {
          this.all = data;
          this.provinces = this.setProvinces();
        },
        error => {
          console.log(error);
        }
      );
  }

  private setProvinces() {
    if (this.all !== undefined ) {
      const result = new Array<object>();
      for (let i = 0; i < this.all.length; i++) {
        const value = this.all[i];
        if (value['item_code'].slice(2, 6) === '0000') {
          result.push(value);
        }
      }
      return result;
    }
  }

  private setCity(province: string) {
    if (this.all !== undefined) {
      const result = new Array();
      for (let i = 0; i < this.all.length; i++) {
        const value = this.all[i];
        if (value['item_code'].slice(0, 2) === province.slice(0, 2)
          && value['item_code'] !== province && value['item_code'].slice(4, 6) === '00') {
          result.push(value);
        }
      }
      return result;
    }
  }

  private setArea(city: string) {
    if (this.all !== undefined) {
      const result = [];
      for (let i = 0; i < this.all.length; i++) {
        const value = this.all[i];
        if (value['item_code'] !== city && value['item_code'].slice(0, 4) === city.slice(0, 4)) {
          result.push(value);
        }
      }
      return result;
    }
  }

  public selectProvince(code: string) {
    this.cityValue = 'undefined';
    this.areaValue = 'undefined';
    this.citys = this.setCity(code);
  }

  public selectCity(code: string) {
    this.areaValue = 'undefined';
    this.areas = this.setArea(code);
  }
}

整個(gè)代碼段沒(méi)必要全部看完,我們可以分成3個(gè)部分來(lái)進(jìn)行分析
1.第一部分(初始化省信息部分)

private setAll() {
    this.threeLinkService.setAll()
      .subscribe(
        data => {
          this.all = data;          //將獲取的json數(shù)據(jù)賦值給all數(shù)組
          this.provinces = this.setProvinces();            //篩選all數(shù)組中所有符合省代碼的省信息
        },
        error => {
          console.log(error);
        }
      );
  }

  private setProvinces() {
    if (this.all !== undefined ) {
      const result = new Array<object>();
      for (let i = 0; i < this.all.length; i++) {
        const value = this.all[i];
        if (value['item_code'].slice(2, 6) === '0000') {           //篩選后4位都為0000的json數(shù)據(jù)
          result.push(value);
        }
      }
      return result;
    }
  }

其中setAll()函數(shù)是將threeLinkService中的setAll()返回的數(shù)據(jù)進(jìn)行處理,然后將數(shù)據(jù)賦值給all數(shù)組,同時(shí)使用setProvince()函數(shù)對(duì)provinces數(shù)組進(jìn)行賦值。

2.第二部分(根據(jù)選擇的省信息,獲取城市信息)

private setCity(province: string) {
    if (this.all !== undefined) {
      const result = new Array();
      for (let i = 0; i < this.all.length; i++) {
        const value = this.all[i];
        if (value['item_code'].slice(0, 2) === province.slice(0, 2)
          && value['item_code'] !== province && value['item_code'].slice(4, 6) === '00') {  //選擇前兩位與省代碼一樣的城市代碼,并且后兩位為00的數(shù)據(jù)源  
          result.push(value);
        }
      }
      return result;
    }
  }
public selectProvince(code: string) {
    this.cityValue = 'undefined';       //重置城市選擇器
    this.areaValue = 'undefined';         //重置地區(qū)選擇器
    this.citys = this.setCity(code);
  }

由于整個(gè)json數(shù)據(jù)部分的結(jié)構(gòu),如下:

{"item_code":"110000","item_name":"北京市"},
  {"item_code":"120000","item_name":"天津市"},
  {"item_code":"130000","item_name":"河北省"},
  {"item_code":"140000","item_name":"山西省"},

所以,我們可以根據(jù)字符串的前兩位來(lái)判斷所選擇的省,然后獲取城市的信息。selectProvince()是一個(gè)響應(yīng)函數(shù),在每次重新選擇省時(shí),都需要重置城市選擇器和地區(qū)選擇器。

3.第三部分(根據(jù)城市信息,獲取地區(qū)信息)

private setArea(city: string) {
    if (this.all !== undefined) {
      const result = [];
      for (let i = 0; i < this.all.length; i++) {
        const value = this.all[i];
        if (value['item_code'] !== city && value['item_code'].slice(0, 4) === city.slice(0, 4)) {
          result.push(value);
        }
      }
      return result;
    }
  }
public selectCity(code: string) {
    this.areaValue = 'undefined';        //每次選擇城市的同時(shí),都重置地區(qū)選擇器
    this.areas = this.setArea(code);
  }

地區(qū)數(shù)據(jù)的選擇與城市數(shù)據(jù)的選擇一樣,都是根據(jù)城市的唯一代碼進(jìn)行匹配,將所有匹配的地區(qū)數(shù)據(jù)放入areas數(shù)組中

  • html代碼部分
<md-select placeholder="請(qǐng)選擇省份" >
  <md-option *ngFor="let province of provinces" [value]="province.item_code" (click)="selectProvince(province.item_code);">
    {{province.item_name}}
  </md-option>
</md-select>
<md-select placeholder="請(qǐng)選擇城市" [(ngModel)]="cityValue">
  <md-option *ngFor="let city of citys" [value]="city.item_code" (click)="selectCity(city.item_code);">
    {{city.item_name}}
  </md-option>
</md-select>
<md-select placeholder="請(qǐng)選擇地區(qū)" [(ngModel)]="areaValue">
  <md-option *ngFor="let area of areas" [value]="area.item_code">
    {{area.item_name}}
  </md-option>
</md-select>

省選擇器的點(diǎn)擊事件就是selectProvince(province.item_code)函數(shù),這函數(shù)可以篩選出后續(xù)的城市信息,重點(diǎn)要強(qiáng)調(diào)的是城市選擇器和地區(qū)選擇器中的[(ngModel)],由于每次重新選擇前面一個(gè)選擇器時(shí),都需要將后面的選擇器進(jìn)行重置,所以這里使用數(shù)據(jù)的雙向綁定的方法,進(jìn)行選擇器的重置,只要將其中的值置為undefined,就可以使選擇器重置。

這個(gè)組件的原理大致就是這樣子,寫(xiě)的有點(diǎn)粗糙,原理可能有些沒(méi)講透,希望讀者可以給我留言或者提問(wèn)

注:這篇博文屬于原創(chuàng)博文,如果有問(wèn)題的可以給我留言,轉(zhuǎn)載注明出處。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,933評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,316評(píng)論 25 708
  • github排名https://github.com/trending,github搜索:https://gith...
    小米君的demo閱讀 4,815評(píng)論 2 38
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,241評(píng)論 4 61
  • 百無(wú)聊賴,拍拍自己,打發(fā)打發(fā),無(wú)助煎熬
    半半兒閱讀 215評(píng)論 0 0