省市區(qū)三級聯(lián)動組件 material angular2

前言

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

組件效果圖

效果圖

組件分析

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

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

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

  • 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));
  }
}

這里我請求了存放在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>;                         //存儲所有的省市區(qū)數(shù)據(jù)
  public provinces: Array<object>;                    //存儲省的信息
  public citys: Array<object>;                       //存儲城市的信息
  public areas: Array<object>;                         //存儲地區(qū)的信息
  public cityValue: string;                               //重置城市選擇器時用到的變量
  public areaValue: string;                            //重置地區(qū)選擇器時用到的變量
  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);
  }
}

整個代碼段沒必要全部看完,我們可以分成3個部分來進行分析
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ù)進行處理,然后將數(shù)據(jù)賦值給all數(shù)組,同時使用setProvince()函數(shù)對provinces數(shù)組進行賦值。

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);
  }

由于整個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ù)字符串的前兩位來判斷所選擇的省,然后獲取城市的信息。selectProvince()是一個響應(yīng)函數(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';        //每次選擇城市的同時,都重置地區(qū)選擇器
    this.areas = this.setArea(code);
  }

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

  • html代碼部分
<md-select placeholder="請選擇省份" >
  <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="請選擇城市" [(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ū)" [(ngModel)]="areaValue">
  <md-option *ngFor="let area of areas" [value]="area.item_code">
    {{area.item_name}}
  </md-option>
</md-select>

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

這個組件的原理大致就是這樣子,寫的有點粗糙,原理可能有些沒講透,希望讀者可以給我留言或者提問

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容