地址選擇控制項開發--如何優雅地回答保全小哥的哲理問題?

来源:http://www.cnblogs.com/alai88/archive/2016/04/20/5412169.html
-Advertisement-
Play Games

"你從哪裡來?” “你要到哪裡去?" 這是保全小哥經常會問的具有哲理性的問題。在互聯網的應用的開發中,也經常會用到有關地址的選擇設置。不管是物流的應用,還是外賣的應用,都會要求用戶設置用戶所在的位置。如果讓用戶來輸入完整的地址,一方面,輸入比較慢,體驗不好。另一方面,輸入的地址不規範,例如:"浙江省 ...


"你從哪裡來?”

“你要到哪裡去?"

這是保全小哥經常會問的具有哲理性的問題。在互聯網的應用的開發中,也經常會用到有關地址的選擇設置。不管是物流的應用,還是外賣的應用,都會要求用戶設置用戶所在的位置。如果讓用戶來輸入完整的地址,一方面,輸入比較慢,體驗不好。另一方面,輸入的地址不規範,例如:"浙江省溫州市永嘉縣",有些人會輸入"浙江溫州永嘉",有些人則會輸入"浙江省永嘉縣",這對服務端的數據處理、分析也帶來不便。

如何開發一個體驗良好的“地址選擇Web控制項”,如何優雅地回答保全小哥的哲理問題?估計是廣大Web應用開發人員一直在思考的問題。與其他一些標準Web控制項(例如:組合框、單選框等)不同,“地址選擇Web控制項”具有區域特征,功能也比較綜合,大部分標準的UI庫都不會提供,所以,搗鼓一下還是很有必要的。

先睹為快

閑話少說,我們先來看看今天我們研究的控制項的最終效果圖(參照天貓的送貨地址設置的效果):

“地址選擇Web控制項”的基本組成:

使用控制項舉例:

<!--需要載入和引用的文件-->
<link rel="stylesheet" href="css/zlbox.css" type="text/css" media="screen" />
<script src="js/jquery-1.7.1.js"></script>
<script src="js/jquery.zlbox.js"></script>

<!--控制項的HTML代碼-->
<div id="company_addr" class="zl_addressbox">
           <div class="ab_showbar tip">
              <div class="tip_info">請選擇省市區</div>
              <div class="value_info">
                  <!--結果顯示容器-->
              </div>
           </div>
           <span class="ab_btn"></span>
           <div class="selectaddr_box">
              <div class="ab_bar">
                 <ul>
                    <li class="sheng current">省份</li>
                    <li class="shi">城市</li>
                    <li class="qu">區縣</li>
                 </ul>
              </div>
              <div class="ab_panel">
                <dl>
                   <dd class="sheng current">
                      <div class="ab_group">
                        <span class="ab_shengtitle">A-G</span>
                        <ul class="ab_sheng ab_item">
                           <li>北京</li>
                           <li>廣東</li>
                        </ul>
                      </div>
                      <div class="ab_group">
                        <span class="ab_shengtitle">T-Z</span>
                        <ul class="ab_sheng ab_item">
                           <li>浙江</li>
                        </ul>
                      </div>
                   </dd>
                   <dd class="shi">
                      <ul class="ab_shi ab_item">
                        <!--市區容器-->
                      </ul>
                   </dd>
                   <dd class="qu">
                      <ul class="ab_qu ab_item">
                        <!--區縣容器-->
                      </ul>
                   </dd>
                </dl>
              </div>
           </div>
        </div>
        <!--End of ZLAddressBox-->


<script type="text/javascript">
    //初始化地址控制項
    $('#company_addr').czl_addressbox({});
</script>

 

為了講解的方便,控制代碼的篇幅,這裡僅僅舉例了北京、廣東、浙江3個省市的“省份/城市/區縣”選擇,數據完整的“全國地址選擇Web控制項”還在搗鼓中,出貨後再向諸位彙報。

基本功能實現

【HTML代碼】

Web控制項涉及的HTML代碼如下:

<!--ZLAddressBox-->
        <div id="company_addr" class="zl_addressbox">
           <div class="ab_showbar tip">
              <div class="tip_info">請選擇省市區</div>
              <div class="value_info">
                  <!--結果顯示容器-->
              </div>
           </div>
           <span class="ab_btn"></span>
           <div class="selectaddr_box">
              <div class="ab_bar">
                 <ul>
                    <li class="sheng current">省份</li>
                    <li class="shi">城市</li>
                    <li class="qu">區縣</li>
                 </ul>
              </div>
              <div class="ab_panel">
                <dl>
                   <dd class="sheng current">
                      <div class="ab_group">
                        <span class="ab_shengtitle">A-G</span>
                        <ul class="ab_sheng ab_item">
                           <li>北京</li>
                           <li>廣東</li>
                        </ul>
                      </div>
                      <div class="ab_group">
                        <span class="ab_shengtitle">T-Z</span>
                        <ul class="ab_sheng ab_item">
                           <li>浙江</li>
                        </ul>
                      </div>
                   </dd>
                   <dd class="shi">
                      <ul class="ab_shi ab_item">
                        <!--市區容器-->
                      </ul>
                   </dd>
                   <dd class="qu">
                      <ul class="ab_qu ab_item">
                        <!--區縣容器-->
                      </ul>
                   </dd>
                </dl>
              </div>
           </div>
        </div>
        <!--End of ZLAddressBox-->

【CSS代碼】

Web控制項涉及到的CSS代碼(zlbox.css)如下:

  1 /**全國地址選擇控制項**/
  2 .zl_addressbox{
  3     position:relative;
  4     width:370px;
  5     background-color:#F08;
  6 }
  7 .zl_addressbox .ab_showbar{
  8     width:100%;
  9     height:30px;
 10     line-height:30px;
 11     border:#A9A9A9 1px solid;
 12     background-color:#FFF;    
 13 }
 14 .zl_addressbox .ab_btn{
 15     position:absolute;
 16     right:0px;
 17     top:1px;
 18     width:30px;
 19     height:30px;
 20     background:#FFF url('img/cb_btn_down.png') no-repeat center center;
 21 }
 22 /**地址選擇面板**/
 23 .zl_addressbox .selectaddr_box{
 24     display:none;
 25     position:absolute;
 26     left:0px;
 27     right:0px;
 28     top:32px;
 29     width:100%;
 30     line-height:30px;
 31     background-color:#FFF;
 32     z-index:888;
 33 }
 34 .zl_addressbox .ab_bar{
 35     width:100%;
 36     height:40px;
 37 }
 38 .zl_addressbox .ab_bar:after{
 39     clear:both;
 40     content:'';
 41     display:table;
 42 }
 43 .zl_addressbox .ab_bar li{
 44     float:left;
 45     width:122px;     /**這裡如果要調整容器大小,需要同步調整**/
 46     height:40px;
 47     line-height:40px;
 48     text-align:center;
 49     background-color:#F0F0F0;
 50     border-left:#CCC 1px solid;
 51     border-bottom:transparent 1px solid ;
 52     cursor:pointer;
 53 }
 54 .zl_addressbox .ab_bar li:first-child{
 55     border-left:none;
 56 }
 57 .zl_addressbox .ab_bar li.current{
 58     color:#009AFD;
 59     background-color:#FFF;
 60     cursor:none;
 61 }
 62 .zl_addressbox .ab_panel{
 63     position:relative;
 64     width:100%;
 65 }
 66 .zl_addressbox .ab_panel dd{
 67     display:none;
 68     position:relative;
 69     width:100%;
 70 }
 71 .zl_addressbox .ab_panel dd.current{
 72     display:block;
 73 }
 74 /**省份面板中的分組**/
 75 .zl_addressbox .ab_panel dd .ab_group{
 76     position:relative;
 77     width:100%;
 78     margin-bottom:20px;
 79 }
 80 .zl_addressbox .ab_panel dd .ab_group span.ab_shengtitle{
 81     display:block;
 82     position:absolute;
 83     top:0px;
 84     width:60px;
 85     height:30px;
 86     line-height:30px;
 87     text-align:center;
 88     font-size:0.8em;
 89     color:#009AFD;
 90 }
 91 .zl_addressbox .ab_panel dd .ab_group .ab_sheng{
 92     margin-left:40px;
 93 }
 94 .zl_addressbox .ab_panel dd ul.ab_item{
 95     margin-top:10px;
 96     margin-bottom:5px;
 97 }
 98 .zl_addressbox .ab_panel dd ul.ab_item:after{
 99     clear:both;
100     display:table;
101     content:'';
102 }
103 .zl_addressbox .ab_panel dd ul.ab_item li{
104     float:left;
105     height:30px;
106     line-height:30px;
107     padding:0px 10px;
108     margin-left:10px;
109     cursor:pointer;
110 } 
111 .zl_addressbox .ab_panel dd ul.ab_item li:hover{
112     color:#009AFD;
113 }
114 .zl_addressbox .ab_panel dd ul.ab_item li.current{
115     border-radius:6px;
116     color:#FFF;
117     background-color:#009AFD;
118 }
119 .zl_addressbox.selected .selectaddr_box{
120     display:block;
121     border-left:1px #CCCCCC solid;
122     border-right:1px #CCCCCC solid;
123     border-bottom:1px #CCCCCC solid;
124     padding-bottom:10px;
125 }
126 .zl_addressbox.selected  .ab_btn{
127     background:#FFF url('img/cb_btn_up.png') no-repeat center center;
128 }
129 /**提示狀態**/
130 .zl_addressbox .ab_showbar .tip_info{
131     display:none;
132     width:90%;
133     padding-left:5px;
134     color:#CCCCCC;
135 }
136 .zl_addressbox .ab_showbar .value_info{
137     display:block;
138     width:90%;
139     padding-left:5px;
140 }
141 .zl_addressbox .ab_showbar .value_info span.sep{
142     color:#CCC;
143     font-size:0.8em;
144 }
145 
146 .zl_addressbox .ab_showbar.tip .value_info{
147     display:none;
148 }
149 .zl_addressbox .ab_showbar.tip .tip_info{
150     display:block;
151 }

結合我們的功能訴求,一級前面介紹的控制項的組成,將HTML代碼與CSS代碼對照起來理解應該比較好理解,所以,關於控制項涉及到的佈局、樣式等細節,就不展開贅述,我們把重點放到JavaScript的代碼部分。開發Web控制項的基本套路與前一篇博文:ZLComboBox自定義控制項開發詳解  類似,本文就著重講解控制項的業務需求以及與ZLComboBox控制項開發不一樣的地方。

JavaScript--閉包實現

與ZLComboBox控制項不同,本文我們採用閉包的方式來構建我們的控制項對象,jQuery插件的基本代碼如下:

$.fn.czl_addressbox = function( options )
   {
       this.each( function()  
       {
          var instance = $.data( this , 'czl_addressbox' );
          
          if( !instance )
          {
            $.data( this, 'czl_addressbox' , $.createAddressBox( options , this ) );  
          
       });//end of each
       
       return this;  //支持鏈式操作
   };

控制項對象通過createAddressBox()來返回一個控制項對象,下麵我們重點來分析一下createAddressBox()的基本組成。

整個控制項對象基於地址的'三級'目錄樹,以id來進行各級行政單位的標識與處理。

整個控制項對外的介面:

   1> 創建控制項時,可以傳入一個對象字面量(options),用於設置預設選中的地址。

   2> 返回當前選中地址的對象字面量:get_addr_obj()。

   3> 傳入一個地址對象字面量:set_addr_obj( new_addr_obj )。

 

業務流程分析:

1> 預設情況下,控制項顯示'請選擇省市區'的提示信息。

2> 單擊控制項'地址欄',顯示下拉的'地址選擇面板';再次單擊'地址欄',隱藏下拉的'地址選擇面板';下拉的'地址選擇面板'反映當前的選擇狀態。

3> 在'省份'面板中選中一個'省級單位'後,自動顯示選中省級單位下的'市級'行政區。

     在'城市'面板中選中一個'市級單位'後,自動顯示選中市級單位下的'區級'行政區。

     在'區縣'面板中選中一個'區級單位'後,自動隱藏'地址選擇面板'。

     所有的選擇結果,都會實時在控制項'地址欄'中顯示出來。

4> 只有選中了'省級'單位之後,才能單擊'市級'單位的頁簽,

     只有選中了'市級'單位之後,才能單擊'區級'單位的頁簽。

5> 當更改了某一級別的選擇結果之後,將它的下一級單位的選擇清空。

     例如:已經選擇了"廣東/深圳",這時候單擊"省份"面板中的"浙江",則原來"城市面板"中的內容被清空,重新設置為"浙江"所包含的城市。

 

綜合業務需求,閉包中的成員可以包括:

私有屬性

  • 保存了'三級地址信息'的對象字面量:addr_box_data
  • 用於記錄選擇結果的對象字面量:addr_obj
  • 一些HTML元素的引用等:例如;地址欄元素ab_showbar

私有函數

  •  選中某個'省級單位','市級單位'和'區級單位'之後的響應函數。

        _selectShengId( sheng_index )

        _selectShiId( shi_index )

        _selectQuId( qu_index )

  • 更新地址欄信息的函數:_updateAddrValue( )
  • 創建控制項時,要執行的初始化函數:_init( options )
  • 相關控制項的註冊函數:_loadEvents( ),這個函數應該在_init()中被調用。

因為整個架構都是基於id來創建,而從界面呈現來看,我們更習慣於'地址名稱',

例如:"浙江省"的id是多少?不去翻閱addr_box_data,我們是回答不上來的。

所以,增加一個輔助函數:getShengIDFromName( sheng_name )

控制項對外提供的介面函數

  • 獲得當前選中的地址信息的對象字面量:get_addr_obj()
  • 設置預設選中的地址信息:set_addr_obj:function( a_obj )

控制項提供的HTML介面

每次更新addr_obj的時候,同步將地址的信息更新到 HTML 元素的data屬性中,名稱為:addr_value。

例如:如果依次選中了:'浙江>杭州>濱江',那麼,addr_value的值為:'浙江_杭州_濱江'。

這種方式的好處是:在應用中直接用$('.zl_addressbox').czl_addressbox({}); 就把所有的addressbox控制項都初始化了。後續要取值時,直接從對應元素的data屬性中獲取即可,而不用去分析如何調用控制項對象。

綜合以上分析,createAddressBox()代碼的基本框架如下:

$.createAddressBox = function( options , element ){
        //私有成員聲明
        var addr_box = $( element );
        //相關的HTML組件
        //......
        
        //省份的選擇控制項
        var ab_sheng_item = addr_box.find( '.ab_sheng>li' );
        
        //保存了'三級地址信息'的對象字面量
        var addr_box_data = {} ;       
        
        //用於記錄選擇結果的對象字面量
               var addr_obj = {};
        
        //私有函數聲明
        var _init = function( options ){
            //載入事件註冊
            _loadEvents();

addr_box.data( 'addr_value' , '' );
//...
        };
        
        //依據a_obj的值初始化控制項的狀態
        var _init_addr_obj = function( a_obj ){
            //......
        }
        
        //更新地址欄中的值
        var _updateAddrValue = function(){
            //......
        };
        
        //選擇序號為sheng_id的省份之後的響應事件
        var _selectShengId = function( sheng_index ){
            //......
        };
        
        //選擇序號為shi_index的城市之後的響應事件
        var _selectShiId = function( shi_index ){
             //......
        };
        //選擇序號為qu_index的區縣之後的響應事件
        var _selectQuId = function( qu_index ){
            //......
        };
        
        //根據省份的名稱,選擇對應的id
        var getShengIDFromName = function( sheng_name ){
            //......
        }
        
        //註冊事件
        var _loadEvents = function(){
            //......    
        };

        //執行初始化函數
        _init( options );

        //創建對象
        var that = {
            get_addr_obj:function(){
                return addr_obj;
            },
            set_addr_obj:function( a_obj ){
                _init_addr_obj( a_obj );
                return ;
            }
        };
        
        
        //返回對象
        return that ;
   }        

JavaScript--事件冒泡

重點看一下'市級'面板和'區級'面板相關選項的單擊事件處理。根據前面的分析,我們發現這兩個面板的選項,是動態變化的,那我們應該如何處理呢?

這讓我們想到了事件的'冒泡'機制,只要註冊相關容器的單擊事件,當選中某個選項時,自然會冒泡到'容器'的處理函數那裡。不難,直接上代碼:

        //註冊事件
        var _loadEvents = function(){
            //......
        
            //單擊'市'下麵的選項的響應事件
            ab_shi_databox.on( 'click' , function( event ){
                //阻止事件冒泡
                event.stopPropagation();
                var $target = $( event.target );
                if( $target.attr( 'tagName' ) === 'li' ){
                    var shi_item = $target ;
                    //如果當前的'市'選項就是選中的選項,則不響應事件,直接返回
                    if( shi_item.hasClass('current') ){
                        return ;
                    }
                    //獲得省份對應的id的值
                    var shi_id = shi_item.index();
                    //響應選中城市之後的響應函數
                    _selectShiId( shi_id );
                    //標記當前選中的"城市"
                    shi_item.addClass('current').siblings().removeClass( 'current' );
                }//如果是子元素li上觸發的事件
                return ;
            });
            
            //單擊'區'下麵的選項的響應事件
            ab_qu_databox.on( 'click' , function( event ){
                //阻止事件冒泡
                event.stopPropagation();
                var $target = $( event.target );
                if( $target.attr( 'tagName' ) === 'li' ){
                    var qu_item = $target ;
                    if( qu_item.hasClass('current') ){
                        return ;
                    }
                    //獲得省份對應的id的值
                    var qu_id = qu_item.index();
                    //響應選中城市之後的響應函數
                    _selectQuId( qu_id );
                    qu_item.addClass('current').siblings().removeClass( 'current' );
                    return ;
                }
            });
        
        };
                

 

優化控制項:

 到目前為止,我們的控制項已經能夠工作了,但是,還有一些可以優化地方,我們一起來分析一下。

JavaScript--單例模式

每次我們使用控制項的時候,都要執行createAddressBox()創建一個對象,根據閉包的特性,每次創建時,閉包中的私有屬性成員都會被單獨創建,作為一個完整的工作區占據記憶體空間。 我們註意到包含"三級地址信息"的addr_box_data也是一個'私有屬性',而這個對象字面量所占的記憶體空間非常大,如果每次調用createAddressBox()都占用一段大記憶體空間,從性能上來看,顯然不是一個好的設計。

因為addr_box_data的內容是固定的,所以,可以把"三級地址信息"保存到一個單獨的全局空間中,

而僅僅在createAddressBox()中引用這個全局空間即可。

   優化方式如下:

   a. 創建一個全局變數:$.zl_addr_box_data。

   b. 在createAddressBox中引用這個全局變數。

相關的代碼示例如下:

$.createAddressBox = function( options , element ){
      //......
      var addr_box_data = $.zl_addr_box_data;         //引用的全局變數
      //......
}    


//保留有全國地址信息的全局變數
   $.zl_addr_box_data = (function( ){
      var that = {
'0':['北京','浙江','廣東'],
'0_0':['北京'],
'0_0_0':['東城','西城','崇文','宣武','朝陽','丰台','石景山','海澱','門頭溝','房山','通州','順義','昌平','大興','懷柔','平谷','密雲','延慶'],
'0_1':['杭州','寧波','溫州','嘉興','湖州','紹興','金華','衢州','舟山','台州','麗水'],
'0_1_0':['上城','下城','江干','拱墅','西湖','濱江','蕭山','餘杭','桐廬','淳安','建德','富陽','臨安'],
'0_1_1':['海曙','江東','江北','北侖','鎮海','鄞州','象山','寧海','餘姚','慈溪','奉化'],
'0_1_2':['鹿城','龍灣','甌海','洞頭','永嘉','平陽','蒼南','文成','泰順','瑞安','樂清'],
'0_1_3':['秀城','嘉善','海鹽','海寧','平湖','桐鄉'],
'0_1_4':['吳興','南潯','德清','長興','安吉'],
'0_1_5':['越城','紹興','新昌','諸暨','上虞','嵊州'],
'0_1_6':['婺城','金東','武義','浦江','磐安','蘭溪','義烏','東陽','永康'],
'0_1_7':['柯城','衢江','常山','開化','龍游','江山'],
'0_1_8':['定海','普陀','岱山','嵊泗'],
'0_1_9':['椒江','黃岩','路橋','玉環','三門','天台','仙居','溫嶺','臨海'],
'0_1_10':['蓮都','青田','縉雲','遂昌','松陽','雲和','慶元','景寧','龍泉'],
'0_2':['廣州','韶關','深圳','珠海','汕頭','佛山','江門','湛江','茂名','肇慶','惠州','梅州','汕尾','河源','陽江','清遠','東莞','中山','潮州','揭陽','雲浮'],
'0_2_0':['荔灣','越秀','海珠','天河','白雲','黃埔','番禺','花都','南沙','蘿崗','增城','從化'],
'0_2_1':['武江','湞江','曲江','始興','仁化','翁源','乳源','新豐','樂昌','南雄'],
'0_2_2':['羅湖','福田','南山','寶安','龍崗','鹽田','光明新區','坪山新區','龍華新區','大鵬新區'],
'0_2_3':['香洲','斗門','金灣'],
'0_2_4':['龍湖','金平','濠江','潮陽','潮南','澄海','南澳'],
'0_2_5':['禪城','南海','順德','三水','高明'],
'0_2_6':['蓬江','江海','新會','台山','開平','鶴山','恩平'],
'0_2_7':['赤坎','霞山','坡頭','麻章','遂溪','徐聞','廉江','雷州','吳

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 此設計模式遵循的設計原則之一:類應該支持擴展,而拒絕修改(Open-Closed Principle) 裝飾者模式簡述 裝飾者模式通過組合的方式擴展對象的特性,這種方式允許我們在任何時候對對象的功能進行擴展甚至是運行時擴展,而若我們用繼承來完成對類的擴展則只能在編譯階段實現,所以在某些時候裝飾者模式 ...
  • 先來說說正向代理 就是普通的代理,記得高中年代偷跑去網吧是要辦卡的 題外話: 就是這貨。。。相信很多80同齡人都有吧。。。 回到正題,那正向代理就不讓你直接訪問網路,而需要登錄一下網吧的某個系統,那個就是代理伺服器,這樣你才能上網 那反向代理其實就是這樣的: 當你訪問淘寶的時候,其實也有很多人在訪問 ...
  • 原型模式就是從一個對象再創建另一個可定製的對象,而不需要知道任何創建的細節。 原型模式本身是比較簡單的,不過其中牽涉到淺複製和深複製的實現,下麵使用.Net自帶的方法和介面分別實現淺複製和深複製: MemberwiseClone方法實現的是淺複製,即如果欄位是值類型,則對該欄位執行逐位複製,如果欄位 ...
  • 一直覺得有些概念還離著自己比較遠,比如ES6,比如React,比如Redux,雖說這些概念早已經火的一塌糊塗,每天逛微博知乎到處都是他們的身影,但感覺好像和自己沒什麼關係。不過最近要開始一個新的項目,一個webapp,開始依然像我以前一樣,頂級組件處理處理邏輯和數據,數據通過組件屬性分發下去,邏輯通 ...
  • 1.圖片寬高固定,這種情況很簡單。水平居中:就在圖片的css中加 dispaly:block;margin:0 auto;垂直居中:自己算出(div的高度-圖片的高度)/2,得到margin-top值即可。2.圖片高度未知,這個佈局比較難實現。一般我是用js做的。水平居中:同上,在圖片的css中加 ...
  • 效果:http://hovertree.com/texiao/jquery/50/現在許多社區,購物等網站都設置簽到功能,打開可以收穫經驗、虛擬幣等,提高用戶粘性,增加瀏覽量,是一個不錯的功能。本文使用jQuery製作了一個簡單的打卡特效。現在jQuery的應用十分廣泛,這裡提供全部版本的jQuer ...
  • 今天遇到一個問題:怎樣實現點擊一個按鈕,在當前的頁面上新增加一個小視窗,展示一個圖片信息? 如圖: 點擊之前: 單擊之後: 分析:要使新增的小視窗不影響父頁面,我們這裡採用iframe的框架的技術。 【<iframe>也應該是框架的一種形式,它與<frame>不同的是,iframe可以嵌在網頁中的任 ...
  • 前言: 創建元素有兩種方法 1)將需要創建的元素,以字元串的形式拼接;找到父級元素,直接對父級元素的innnerHTML進行賦值。 2)使用Document、Element對象自帶的一些函數,來實現動態創建元素(創建元素 => 找到父級元素 => 在指定位置插入元素) 一、字元串拼接形式 為了更好的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...