再遇angular(angular4項目實戰指南)

来源:http://www.cnblogs.com/floor/archive/2017/08/08/7302740.html
-Advertisement-
Play Games

這兩天看了看angular4的文檔,發現他和angular1.X的差別真的是太大了,官方給出的那個管理英雄的Demo是一個非常好的入門項目,這裡給出一個管理個人計劃的小項目,從頭至尾一步一步講解如何去實現他,希望對你有所幫助。這篇文章不會講解如何去用angular,這部分東西你可以參考官網,本文講解... ...


這兩天看了看angular4的文檔,發現他和angular1.X的差別真的是太大了,官方給出的那個管理英雄的Demo是一個非常好的入門項目,這裡給出一個管理個人計劃的小項目,從頭至尾一步一步講解如何去實現他,希望對你有所幫助。這篇文章不會講解如何去用angular4,這部分東西你可以參考官網,本文講解的是用angular做一個小項目的全過程。寫的比較倉促,疏漏難免,請各位多多指點。

本項目是angular4.0的一個Demo,可以實現對個人計劃的管理。目的是分享一下個人做一個angular項目的一般做法,希望能為一些朋友提供參考。項目參考了vue-tutorial,在此對原作者表示感謝。


git地址:https://github.com/yibingxiong/ng-plan
博客地址:http://www.cnblogs.com/floor/

項目架構

Markdown


開發過程詳解

本開發過程不對angular4.0的使用進行詳細講解,一些基本概念和一些工具的安裝使用請參考官網

1. 初始化項目

  • 使用angular-cli搭建項目
    ng new ng-plan
  • 啟動項目
  • cd ng-plan
  • ng serve
    Markdown
  • 訪問localhost:4200/查看效果
    Markdown
    如果能夠看到這個效果證明你完成了天才第一步(不是雀式紙尿褲哦)

2. 做一個首頁

  • 引入bootstrap樣式庫

為了簡化樣式編寫,直接用個第三方庫bootstrap,在/src/index.html的heade引入,如下
<link href="http://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

  • 修改/src/app/app.component.html
<nav class="navbar navbar-default">
  <div class="container">
    <div class="navbar-header">
      <a class="navbar-brand" href="#">
          <i class="glyphicon glyphicon-time"></i>
          計劃板
        </a>
    </div>
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">首頁</a></li>
        <li><a href="#">計劃列表</a></li>
      </ul>
    </div>
  </div>
</nav>
<div class="container">
  <div class="col-sm-3">
    <div class="panel panel-default">
      <div class="panel-heading">
        <h1 class="text-center">已有時長</h1>
      </div>
      <div class="panel-body">
        <h1 class="text-center">1 小時</h1>
      </div>
    </div>
  </div>
  <div class="col-sm-9">
    <div class="jumbotron">
      <h1>任務追蹤</h1>
      <p>
        <strong>
          <a href="#">創建一個任務</a>
        </strong>
      </p>
    </div>
  </div>
</div>

效果如下

Markdown

3. 自己動手做一個組件

  • 使用angular-cli創建組件 ng g component navigation

Markdown

  • 將/src/app/app.component.html中的導航部分移到/src/app/navigation/navigation.component.html

Markdown

  • 使用我們的navigation組件

Markdown

從上圖可以看見使用命令行創建組件,組件會被自動註冊到根模塊中,所以直接使用就可以了
直接在/src/app/app.component.html最上邊加上

<app-navigation></app-navigation>

如果不出現意外的話,你看到的效果應該和2中效果一樣,那為什麼要這樣做呢?方便維護,便於復用。在這個小項目你可能並不能看出他的好處,而且本項目將導航做成獨立組件沒有太大意義。

4. 做個路由

  • 在app.module.ts中導入路由模塊
import { RouterModule }   from '@angular/router';
  • 配置我們的路由

現在我們的/src/app/module.ts應該是下邊這個樣子

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';

import { AppComponent } from './app.component';
import { NavigationComponent } from './navigation/navigation.component';

@NgModule({
  declarations: [
    AppComponent,
    NavigationComponent,
  ],
  imports: [
    BrowserModule,
    RouterModule.forRoot([
      { path: '', redirectTo: '/home', pathMatch: 'full' },
      { path: 'home',  component: HomeComponent },
    ])
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

可以看到imports中做了路由配置,此時運行會出錯,因為還沒有Home組件

  • 指定路由出口

將/src/app/app.component.html改為如下

<app-navigation></app-navigation>
<div class="container">
  <div class="col-sm-3">
    <div class="panel panel-default">
      <div class="panel-heading">
        <h1 class="text-center">已有時長</h1>
      </div>
      <div class="panel-body">
        <h1 class="text-center">1 小時</h1>
      </div>
    </div>
  </div>
  <div class="col-sm-9">
    <router-outlet></router-outlet>
  </div>
</div>

可以發現一部分內容被替換為<router-outlet></router-outlet>這樣,路由匹配的內容將會在這裡顯示。

  • 創建Home組件

上邊發現我們home找不到,現在創建這個組件,與上邊創建navigation是類似的
直接運行

ng g component home

angular-cli會幫我們做好一切
運行效果如下

Markdown

下麵修改我們的Home組件,更改他的html文件如下

<div class="jumbotron">
  <h1>任務追蹤</h1>
  <p>
    <strong>
      <a>創建一個任務</a>
    </strong>
  </p>
</div>

效果如下

Markdown

發現和前面的效果基本一樣了,不過不要著急,我們慢慢來!

5. 創建計劃列表頁

這其實還是創建一個組件,所以我們還是用命令行來搞!

  • 第一步
ng g component plan-list
  • 第二步 加到路由(修改app.module.ts)
{ path: 'planlist', component: PlanListComponent },

Markdown

沒毛病!

  • 第四步 完善計劃列表
  • 修改/src/app/plan-list/plan-list.component.html
  <div class="time-entries">
  <div class="list-group">
    <a class="list-group-item">
      <div class="row">
        <div class="col-sm-2 user-details">
          <img src="http://pic.dfhon.com/pictures/20100401/141048.jpg" class="avatar img-circle img-responsive" />
          <p class="text-center">
            <strong>
              大熊
            </strong>
          </p>
        </div>
        <div class="col-sm-2 text-center time-block">
          <h3 class="list-group-item-text total-time">
            <i class="glyphicon glyphicon-time"></i>
            1
          </h3>
          <p class="label label-primary text-center">
            <i class="glyphicon glyphicon-calendar"></i>
            2017-08-04
          </p>
        </div>
        <div class="col-sm-7 comment-section">
          一定要完成
        </div>
        <div class="col-sm-1">
          <button class="btn btn-xs btn-danger delete-button">
          X
          </button>
        </div>
      </div>
    </a>
    <a class="list-group-item">
      <div class="row">
        <div class="col-sm-2 user-details">
          <img src="http://pic.dfhon.com/pictures/20100401/141048.jpg" class="avatar img-circle img-responsive" />
          <p class="text-center">
            <strong>
              大熊
            </strong>
          </p>
        </div>
        <div class="col-sm-2 text-center time-block">
          <h3 class="list-group-item-text total-time">
            <i class="glyphicon glyphicon-time"></i>
            1
          </h3>
          <p class="label label-primary text-center">
            <i class="glyphicon glyphicon-calendar"></i>
            2017-08-04
          </p>
        </div>
        <div class="col-sm-7 comment-section">
          一定要完成
        </div>
        <div class="col-sm-1">
          <button class="btn btn-xs btn-danger delete-button">
          X
          </button>
        </div>
      </div>
    </a>
  </div>
</div>
  • 修改/src/app/plan-list/plan-list.component.css
  .avatar {
      height: 75px;
      margin: 0 auto;
      margin-top: 10px;
      margin-bottom: 10px;
}
.user-details {
      background-color: #f5f5f5;
      border-right: 1px solid #ddd;
      margin: -10px 0;
}
.time-block {
    padding: 10px;
}
.comment-section {
    padding: 20px;
}
  • 查看效果

Markdown

5. 讓導航可點

目前我們的導航還不能點擊,下麵解決這個問題,修改/src/app/navigation/navigation.component.html

<nav class="navbar navbar-default">
  <div class="container">
    <div class="navbar-header">
      <a class="navbar-brand" routerLink="/" routerLinkActive="active">
          <i class="glyphicon glyphicon-time"></i>
          計劃板
        </a>
    </div>
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li routerLinkActive="active"><a routerLink="/home">首頁</a></li>
        <li routerLinkActive="active"><a routerLink="/planlist" >計劃列表</a></li>
      </ul>
    </div>
  </div>
</nav>

這樣你就可以在首頁和計劃列表點來點去了。

6. 用假數據渲染planlist

  • 修改/src/app/plan-list/plan-list.component.ts提供數據
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-plan-list',
  templateUrl: './plan-list.component.html',
  styleUrls: ['./plan-list.component.css']
})
export class PlanListComponent implements OnInit {
  plans = [
    {
      name: '大熊',
      date: '2017-8-8',
      totalTime: 1,
      comment: '學習到天亮'
    },
    {
      name: '大熊',
      date: '2017-8-8',
      totalTime: 1,
      comment: '學習到天亮'
    },
    {
      name: '大熊',
      date: '2017-8-8',
      totalTime: 1,
      comment: '學習到天亮'
    }
  ];

  constructor() { }

  ngOnInit() {
  }

}
  • 使用ngFor渲染列表,修改/src/app/plan-list/plan-list.component.html
<div class="time-entries">
  <div class="list-group">
    <a class="list-group-item" *ngFor="let plan of plans">
      <div class="row">
        <div class="col-sm-2 user-details">
          <img src="http://pic.dfhon.com/pictures/20100401/141048.jpg" class="avatar img-circle img-responsive" />
          <p class="text-center">
            <strong>
             {{plan.name}}
            </strong>
          </p>
        </div>
        <div class="col-sm-2 text-center time-block">
          <h3 class="list-group-item-text total-time">
            <i class="glyphicon glyphicon-time"></i>
            {{plan.totalTime}}
          </h3>
          <p class="label label-primary text-center">
            <i class="glyphicon glyphicon-calendar"></i>
            {{plan.date}}
          </p>
        </div>
        <div class="col-sm-7 comment-section">
          {{plan.comment}}
        </div>
        <div class="col-sm-1">
          <button class="btn btn-xs btn-danger delete-button">
          X
          </button>
        </div>
      </div>
    </a>
  </div>
</div>

7. 用服務管理我們的數據

  • 建立計劃類
  • 在app下建立bean目錄,作為我們存放基本數據類的地方,然後建立plan.js,如下所示
    Markdown
  • 在app下新建service目錄,用於存放我們的服務,然後進入該目錄運行ng g service plan創建服務,如下所示:
    Markdown
  • 修改剛剛創建的服務的ts文件如下:
 import { Injectable } from '@angular/core';
import { Plan } from '../bean/plan';
@Injectable()
export class PlanService {
  plans: Plan[];
  constructor() {
    this.plans = [
    {
      id: 11,
      name: '大熊',
      date: 100000,
      totalTime: 1,
      comment: '學習到天亮'
    },
    {
      id: 22,
      name: '大熊',
      date: 100000,
      totalTime: 1,
      comment: '學習到天亮'
    },
    {
      id: 33,
      name: '大熊',
      date: 100000,
      totalTime: 1,
      comment: '學習到天亮'
    }];
   }
   getPlans() {
    return this.plans;
   }
  addPlan(newplan: Plan) {
    this.plans.push(newplan);
  }
  deletePlan(id: number) {
    let index = 0;
    for (let i = 0; i < this.plans.length; i++) {
      if (this.plans[i].id === id) {
        index = i;
        break;
      }
    }
    this.plans.splice(index, 1);
  }
  getPlan(id: number) {
    for (let i = 0; i < this.plans.length; i++) {
      if (this.plans[i].id === id) {
        return this.plans[i];
      }
    }
  }
}
  • 在app.module.ts中加入服務依賴
    import進創建的服務,並加入到providers中,如下:
 import { PlanService } from './service/plan.service';
 providers: [PlanService],
  • 在plan-list中註入服務並使用
import { Component, OnInit } from '@angular/core';
import { PlanService } from '../service/plan.service';
import { Plan } from '../bean/plan';
@Component({
  selector: 'app-plan-list',
  templateUrl: './plan-list.component.html',
  styleUrls: ['./plan-list.component.css']
})
export class PlanListComponent implements OnInit {
  plans: Plan[];

  constructor(private planService: PlanService) { }

  ngOnInit() {
    this.plans = this.planService.getPlans();
  }

}

可以看到,我將原來寫死在這個組件的plans去掉了,而是去調用了一個服務獲取我所需要的數據。至此,你所看到的效果與原來的無異,但是我們的項目又向前買進了一大步。

8. 刪除計劃

下麵看一下如何刪除一個計劃,這裡主要用到的是事件的綁定。

  • 首先定義刪除事件處理函數。在/src/app/plan-list/plan-list.component.ts添加如下事件處理函數
  // 刪除計劃
  deletePlan (plan) {
    this.planService.deletePlan(plan.id);
    this.plans = this.planService.getPlans();
  }
  • 在模板中綁定這個事件處理函數
    Markdown
  • 這樣你可以點擊叉叉刪除計划了
    Markdown

9. 創建一個管道來格式化我們的日期

同樣的數據在前端的顯示可能要求不同,這時需要我們對數據進行一些格式化,管道這種東西是你的首選。

  • 按如下操作創建初始化管道

Markdown

觀察文件變化和app.module的變化

Markdown

  • 修改我們的/home/yibingxiong/ng-plan/src/app/pipe/data-format.pipe.ts如下
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'dataFormat'
})
export class DataFormatPipe implements PipeTransform {

  transform(value: number): String {
    const d = new Date();
    d.setTime(value);
    const year = d.getFullYear();
    const month = d.getMonth() + 1;
    const date = d.getDate();
    const h = d.getHours();
    const m = d.getMinutes();
    const s = d.getSeconds();
    return (year + '-' + (month < 10 ? ('0' + month) : month) + '-' +
    (date < 10 ? ('0' + date) : date) + ' ' + (h < 10 ? ('0' + h) : h) +
    ':' + (m < 10 ? ('0' + m) : m) + ':' +
    (s < 10 ? ('0' + s) : s));
  }

}
  • 使用我們的管道,如圖所示

Markdown

10. 為我們的planservice添加一個計算總是長的方法

Markdown

在app.component中使用

Markdown

Markdown

但是會法現一個問題,當刪除計劃時總時長沒有響應變化,下麵設法解決這個問題。

11. 用service做一個共用的數據狀態

經過一番艱苦卓絕的尋找,我終於在https://scotch.io/tutorials/get-angular-1-features-in-angular-2#toc-global-communication-with-services 找到了一個比較簡單的解決方法,雖然我也不是太理解這個方法,不過能用。下麵將我做的修改的文件列出來供你參考。此問題的解決還可以用一個些數據狀態庫。

// /home/yibingxiong/ng-plan/src/app/service/plan.service.ts
import { Injectable } from '@angular/core';
import { Plan } from '../bean/plan';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class PlanService {
  plans: Plan[];
  totalTime = 0;
  totalTime$ = new BehaviorSubject<number>(this.totalTime);
  constructor() {
    this.plans = [
    {
      id: 11,
      name: '大熊',
      date: 100000,
      totalTime: 1,
      comment: '學習到天亮'
    },
    {
      id: 22,
      name: '大熊',
      date: 100000,
      totalTime: 1,
      comment: '學習到天亮'
    },
    {
      id: 33,
      name: '大熊',
      date: 100000,
      totalTime: 1,
      comment: '學習到天亮'
    }];
    this.totalTime = this.getTotalTime2();
   }
  getPlans() {
   return this.plans;
  }
  // 添加計劃
  addPlan(newplan: Plan) {
    this.totalTime = this.getTotalTime2();
    this.updateTotalTimeSbj(this.totalTime);
    this.plans.push(newplan);
  }
  // 刪除計劃
  deletePlan(id: number) {
    let index = 0;
    for (let i = 0; i < this.plans.length; i++) {
      if (this.plans[i].id === id) {
        index = i;
        break;
      }
    }
    this.plans.splice(index, 1);
    this.totalTime = this.getTotalTime2();
    this.updateTotalTimeSbj(this.totalTime);
  }
  // 獲得一個計劃
  getPlan(id: number) {
    for (let i = 0; i < this.plans.length; i++) {
      if (this.plans[i].id === id) {
        return this.plans[i];
      }
    }
  }
  // 計算計劃總時間
  getTotalTime2() {
    let t = 0;
    for (const p of this.plans) {
      t += p.totalTime;
    }
    return t;
  }
  get getTotalTime(): number {
    return this.totalTime;
  }
  private updateTotalTimeSbj(value) {
    this.totalTime$.next(value);
  }
}
// /home/yibingxiong/ng-plan/src/app/app.component.ts
import { Component } from '@angular/core';
import { PlanService } from './service/plan.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor(private planService: PlanService) {

  }
  title = 'app';
}
// /home/yibingxiong/ng-plan/src/app/app.component.html
<app-navigation></app-navigation>
<div class="container">
  <div class="col-sm-3">
    <div class="panel panel-default">
      <div class="panel-heading">
        <h1 class="text-center">已有時長</h1>
      </div>
      <div class="panel-body">
        <h1 class="text-center">{{planService.getTotalTime}} 小時</h1>
      </div>
    </div>
  </div>
  <div class="col-sm-9">
    <router-outlet></router-outlet>
  </div>
</div>

12. 添加計劃

  • 老規矩,先創建頁面組件

Markdown

  • 添加到路由
  • 在/home/yibingxiong/ng-plan/src/app/app.module.ts的路由添加

{ path: 'create', component: CreateComponent },

  • 修改/home/yibingxiong/ng-plan/src/app/home/home.component.html

<a routerLink="/create">創建一個任務</a>

  • 完善添加計劃頁面
    修改/home/yibingxiong/ng-plan/src/app/create/create.component.html
<div class="form-horizontal">
  <div class="form-group">
    <div class="col-sm-6">
      <label>日期</label>
      <input
        type="date"
        class="form-control"
        placeholder="Date"
      />
    </div>
    <div class="col-sm-6">
      <label>時間</label>
      <input
        type="number"
        class="form-control"
        placeholder="Hours"
      />
    </div>
  </div>
  <div class="form-group">
    <div class="col-sm-12">
      <label>備註</label>
      <input
        type="text"
        class="form-control"
        placeholder="Comment"
      />
    </div>
  </div>
  <button class="btn btn-primary">保存</button>
  <a class="btn btn-danger">取消</a>
  <hr>
</div>
  • 做添加計劃事件處理
  • 創建事件處理函數
  <div class="form-horizontal">
  <div class="form-group">
    <div class="col-sm-6">
      <label>日期</label>
      <input
        type="date"
        class="form-control"
        placeholder="Date"
        [(ngModel)]="newplan.date"
      />
    </div>
    <div class="col-sm-6">
      <label>時間</label>
      <input
        type="number"
        class="form-control"
        placeholder="Hours"
        [(ngModel)]="newplan.totalTime"
      />
    </div>
  </div>
  <div class="form-group">
    <div class="col-sm-12">
      <label>備註</label>
      <input
        type="text"
        class="form-control"
        placeholder="Comment"
        [(ngModel)]="newplan.comment"
      />
    </div>
  </div>
  <button class="btn btn-primary" (click)="addPlan(newplan)">保存</button>
  <a class="btn btn-danger">取消</a>
  <hr>
</div>
  • 更新模板
 <div class="form-horizontal">
  <div class="form-group">
    <div class="col-sm-6">
      <label>日期</label>
      <input
        type="date"
        class="form-control"
        placeholder="Date"
        [(ngModel)]="newplan.date"
      />
    </div>
    <div class="col-sm-6">
      <label>時間</label>
      <input
        type="number"
        class="form-control"
        placeholder="Hours"
        [(ngModel)]="newplan.totalTime"
      />
    </div>
  </div>
  <div class="form-group">
    <div class="col-sm-12">
      <label>備註</label>
      <input
        type="text"
        class="form-control"
        placeholder="Comment"
        [(ngModel)]="newplan.comment"
      />
    </div>
  </div>
  <button class="btn btn-primary" (click)="addPlan(newplan)">保存</button>
  <a class="btn btn-danger">取消</a>
  <hr>
</div>
  • 取消返回處理
    添加location依賴
    Markdown
    在create組件註入並使用
    Markdown
    在模板添加事件
<a class="btn btn-danger" (click)="cancel()">取消</a>

13. 去掉假數據,並添加無數據支持

修改planService,移除假數據
Markdown
在planlist中加入無數據判斷
Markdown


總結一下

本文是我學習angular4兩個晚上做的一個小Demo,我是一邊做項目一邊寫的這個文檔,所以按照我的文檔操作一般可以順利完成項目,但是難免有一些疏漏,請自行查找問題所在。
本項目雖小,但是他將angular的一些和性要點都用到了。

  • 數據單向綁定
  • 數據雙向綁定
  • 事件
  • 依賴註入
  • 組件
  • 服務
  • 管道
  • 路由
  • 模板指令
  • 命令行用法

本項目的結構僅供參考,你可以搭建更加清晰的項目結構。例如將頁面組件都放到page目錄,將一些碎片化的組件放到components目錄,這都是可以的,你可以靈活運用。非常感謝你能如此耐性的看到這裡,希望本文能對你有所幫助。
最後,要是你覺得這篇文章還不錯,請在我的博客http://www.cnblogs.com/floor/ 點個關註,或者點個推薦。或者幫忙點一下star,github地址:https://github.com/yibingxiong/ng-plan


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

-Advertisement-
Play Games
更多相關文章
  • select 獲取select下的所有option 用op=select.options option屬性:op[1].value,op[1].text; //獲取選中項的索引 os.selectedIndex; //獲取當前選中項 select.options[os.selectedIndex]; ...
  • 解構通俗點說,就是通過一種特定格式,快捷的讀取對象/數組中的數據的方法, es6之前,我們通過對象名稱[鍵] 讀取數據 上面第5行就是一個簡單的數據解構過程: 1,右邊如果是對象,左邊解構的語法也要用對象格式, 如果解構的數據是數組,左邊就用數組格式 2,name, age是局部變數 3,解構出來的 ...
  • 主題:創建對象 原型模式 JavaScript中的每個對象都有一個prototype屬性(原型屬性),這個屬性是一個指針,指向一個對象,而這個對象可以由一些屬性和方法組成。被指向的對象,可以是多個對象的原型,這樣創建的對象就共用了一個原型對象。 這裡可提煉一下,用更簡潔的方式實現。但需要註意cont ...
  • 騰訊發佈 Omix 1.0 用 JSX 或 hyperscript 創建用戶界面 今天,騰訊正式開源發佈 Omix 1.0, 讓開發者使用 JSX 或 hyperscript 創建用戶界面。 "Github" 功能特性 超級快的速度, "點擊這裡體驗一下" 超小的尺寸, 7 KB (gzip) 良好 ...
  • 示例代碼,關鍵位置做了註釋,請查看代碼: 執行運行代碼,效果為: ...
  • css ...
  • Web前端技術由html、css和javascript三大部分構成,是一個龐大而複雜的技術體系,其複雜程度不低於任何一門後端語言。而我們在學習它的時候往往是先從某一個點切入,然後不斷地接觸和學習新的知識點,因此對於初學者很難理清楚整個體系的脈絡結構。本文將對Web前端知識體系進行簡單的梳理,對應的每 ...
  • 以下是正常請求ajax的格式,其中當後臺介面支持跨域時,dataType需設置成jsonp;當後臺返回格式為json且不支持跨域時,dataType要設置成json; 但是有時候請求狀態為200,卻還是進入error,這時需查看後臺的回調函數名稱是否為預設(callback),如不是則需在參數中加入 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...