整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          ASP.NET Core模型綁定 - 基礎篇

          ASP.NET Core模型綁定 - 基礎篇
          么是模型綁定?模型綁定是從HTTP請求獲取數據的一個過程并且將他們提供給Action方法的參數,模型包含了構成應用程序業務邏輯的數據,它們包含了數據庫或者另外數據源中的數據

          在ASP.NET Core處理模型有兩個核心的概念

          1 Model Binding – 從HTTP請求提取數據的一個過程,并將數據提供給Action方法的參數
          2 Model Validation – 處理模型屬性驗證的一個過程以至于未驗證的實體不能進入數據庫

          模型綁定分為基礎和高級分別兩篇,在這節中,我們學習關于模型綁定處理的細節

          1 ASP.NET Core 模型綁定例子

          我們通過一個例子來了解模型綁定的概念,在Visual Studio 2022 中創建一個ASP.NET Core Web App (Model-View-Controller) 項目,名稱為AspNetCore.ModelBinding

          Models & Repository

          在Models文件夾下添加一個新的類叫EmployeeDetails.cs,這定義了2個兩個類和一個枚舉:

          • namespace AspNetCore.ModelBinding.Models{ public class Employee { public int Id { get; set; } public string Name { get; set; } public DateTime DOB { get; set; } public Address HomeAddress { get; set; } public Role Role { get; set; } } public class Address { public string HouseNumber { get; set; } public string Street { get; set; } public string City { get; set; } public string PostalCode { get; set; } public string Country { get; set; } } public enum Role { Admin, Designer, Manager }}
            在Models文件夾下創建一個新的文件Repository.cs,定義接口并實現該接口:
            • namespace AspNetCore.ModelBinding.Models{ public interface IRepository { IEnumerable<Employee> Employee { get; } Employee this[int id] { get; set; } } public class EmployeeRepository : IRepository { private Dictionary<int, Employee> employee=new Dictionary<int, Employee> { [1]=new Employee { Id=1, Name="John", DOB=new DateTime(1980, 12, 25), Role=Role.Admin }, [2]=new Employee { Id=2, Name="Michael", DOB=new DateTime(1981, 5, 13), Role=Role.Designer }, [3]=new Employee { Id=3, Name="Rachael", DOB=new DateTime(1982, 11, 25), Role=Role.Designer }, [4]=new Employee { Id=4, Name="Anna", DOB=new DateTime(1983, 1, 20), Role=Role.Manager } };
              public IEnumerable<Employee> Employee=> employee.Values;
              public Employee this[int id] { get { return employee.ContainsKey(id) ? employee[id] : ; } set { employee[id]=value; } } }}

              我們創建repository并且創建4個員工,我們使用4個員工的數據幫助我們理解模型綁定的概念

              Controllers & Views

              在Controllers文件夾下編輯HomeController.cs文件,通過依賴注入從構造函數中獲取EmployeeRepository 倉儲類,更新HomeController.cs 文件代碼如下:
              • using AspNetCore.ModelBinding.Models;using Microsoft.AspNetCore.Mvc;namespace AspNetCore.ModelBinding.Controllers{ public class HomeController : Controller { private IRepository repository; public HomeController(IRepository repo) { repository=repo; } public IActionResult Index(int id=1) { return View(repository[id]); } }}
                在Views->Home文件下編輯Index.cshtml 視圖文件以至于它能接收到Employee模型并綁定employee屬性在HTML表格,Index 代碼如下:
                • @model Employee@{ ViewData["Title"]="Index";}<h2>Employee</h2><table class="table table-bordered align-middle"> <tr><th>Id:</th><td>@Model.Id</td></tr> <tr><th>Name:</th><td>@Model.Name</td></tr> <tr><th>Date of Birth:</th><td>@Model.DOB.ToShortDateString()</td></tr> <tr><th>Role:</th><td>@Model.Role</td></tr></table>

                  注冊Repository作為服務

                  在Program.cs類中注冊EmployeeRepository 服務,以至于控制器能夠通過依賴注入訪問這個類,代碼如下:
                  builder.Services.AddSingleton<IRepository, EmployeeRepository>();

                  在應用中更新下面代碼:

                  • using ModelBindingValidation.Models;var builder=WebApplication.CreateBuilder(args);// Add services to the container.builder.Services.AddSingleton<IRepository, EmployeeRepository>();builder.Services.AddControllersWithViews();var app=builder.Build();...
                    現在運行項目并且進入URL– /Home/Index/1,將看到employee為1的員工編號顯示在瀏覽器,圖片如下:

                    2 理解模型綁定

                    ASP.NET Core模型綁定在整個過程發揮什么作用呢?我們請求的URL包含了employee id的值(給與第三段的URL是1) /Home/Index/1

                    在Program.cs 類中有默認路由,路由指定了3個URL段,Id是變量
                    • app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}" );
                      現在,我們看到Index方法有一個Id參數
                      • public IActionResult Index(int id=1){ return View(repository[id]);}
                        ASP.NET Core模型綁定處理過程從URL中獲取的Id值,并且將Id值通過參數提供給action方法

                        模型綁定會從下面3個地方查詢值:

                        1 表單數據值

                        2 路由變量

                        3 查詢字符串

                        從表單數據開始檢查,然后路由變量,最后是查詢字符串,在這種情況下,框架如果沒有在表單數據中發現Id的值, 接著會檢查路由變量,發現有個路由變量的值叫Id,然后停止搜索, 接下來不會搜索查詢字符串
                        搜索順序是非常重要,如果我們打開URL– /Home/Index/2?id=1 ,然而我們將會看到Employee Id 為2的記錄, 如下圖所示:

                        這是為什么Employee 為2的員工被顯示,因為在查詢字符串Id的值(即1)之前框架在路由變量中發現了Id(即2)值,因此2的值被提供給action方法參數,如果我們打開URL-Home/Index?id=3,然而Employee Id為3的員工將被顯示:

                        在這種情況下,框架沒有發現Id的值在URL段,因此它將搜索查詢字符串發現Id為3的值
                        3 模型綁定默認值

                        如果ASP.NET Core在這三個地方沒有發現綁定的值,會發生什么呢?– 表單數據值,路由變量&查詢字符串,在這種情況下,它將根據action方法定義的類型提供默認值,這些默認值是:

                        1 int類型為0

                        2 string類型為""

                        3 時間類型為01-01-0001 00:00:00

                        4 float類型為0

                        在Index方法代碼中我們測試一下模型綁定默認值:
                        • public IActionResult Index(int id){ if (id==0) id=1; return View(repository[Convert.ToInt32(id)]);}
                          我們把參數id默認值移除掉,接下來我們在Index方法中打斷點,然后運行應用程序并且進入URL – /Home/Index,注意在這個url中沒有給定第三個參數employee id,因此 現在模型綁定將提交默認值,當斷點命中時,我們將鼠標移動到id變量上檢查一下值,你將看到值0,如下圖所示:

                          當ASP.NET Core 沒有給employee id 值,因此它會為id參數綁定默認值,Id參數是int類型,默認值是0,因此模型綁定提供了默認值為0
                          你能獲取到它 – 如果Id參數類型修改為string,然而模型綁定將給與默認值""

                          我們數據中沒有員工Id為0,因此我們在if代碼塊中賦值為1,這將幫助我們阻止運行時錯誤,我們可以通過使用Try-Catch 塊處理運行時錯誤

                          注意可空類型的默認值為,現在修改Index方法有一個able int類型參數,代碼如下:

                          • public IActionResult Index(int? id){ if (id==) id=1; return View(repository[Convert.ToInt32(id)]);}

                            運行你的應用程序并且進入URL– /Home/Index,現在通過斷點來檢查id的值, 這時你將發現它的值為

                            4 模型綁定簡單類型

                            當ASP.NET Core 綁定簡單類型時,將會把值轉換為方法的參數類型,簡單類型是– string,int,bool,float,datetime,decimal等
                            讓我們通過一個簡單的例子來了解一下:
                            • public IActionResult Index(int? id){ if (id==) id=1; return View(repository[Convert.ToInt32(id)]);}
                              Index方法參數是int類型因此ASP.NET Core 框架會自動轉換url中id段變量的值到int值
                              案例 1 : 針對 URL – /Home/Index/1
                              當強求的URL包含的id值為int,像– /Home/Index/1 框架會成功轉換1的值到int,因此方法參數會收到參數為1
                              案例 2 : 針對 URL – /Home/Index/John

                              如果你收到要給URL,Id值是字符串 像– /Home/Index/John 在這種情況下,框架將嘗試把John轉換到int值,這時不能轉化,因此action 方法接收到id的參數為

                              5 模型綁定復雜類型
                              當action方法的參數是復雜類型,像類對象,然而模型綁定會指定綁定每個復雜類型的公共屬性

                              模型綁定查找公共屬性從下面三個地方:

                              1 表單數據
                              2 路由變量
                              3 查詢字符串
                              這個是非常重要的感念,你將在你的項目中再次使用,面試時也經常問到這個問題,因此我們創建一個例子理解它

                              在Home Controller中添加Create方法,這兩個方法如下:

                              • public IActionResult Create()=> View();[HttpPost]public IActionResult Create(Employee model)=> View("Index", model);
                                HTTP GET版本的Create方法選擇默認View并且沒有傳遞任何模型給它,HTTP POST 版本的Create方法有一個Employee參數的類型(是一個復雜類型)

                                模型綁定的功能是從Http請求中提取Employee類公共屬性,并且將它提供給Create方法的參數,該方法傳遞Employee模型對象到默認View

                                接下來在Views->Home 文件夾下創建Create View,它的代碼給與如下:
                                • @model Employee@{ ViewData["Title"]="Create Employee";}<h2>Create Employee</h2><form asp-action="Create" method="post"> <div class="form-group"> <label asp-for="Id"></label> <input asp-for="Id" class="form-control" /> </div> <div class="form-group"> <label asp-for="Name"></label> <input asp-for="Name" class="form-control" /> </div> <div class="form-group"> <label asp-for="DOB"></label> <input asp-for="DOB" class="form-control" /> </div> <div class="form-group"> <label asp-for="Role"></label> <select asp-for="Role" class="form-control" asp-items="@new SelectList(Enum.GetNames(typeof(Role)))"></select> </div> <button type="submit" class="btn btn-primary">Submit</button></form>
                                  這個View包含了一個表單并且綁定了Employee實體一些公共屬性,當表單被提交這些值將被提交到HTTP POST版本的Create方法
                                  Create方法需要Employee對象的參數,因此模型綁定過程首先從表單數據中查找Employee對象的每個公共屬性的值(Id, Name, DOB, Role)
                                  表單數據包含了這些值,使用asp-for幫助標簽作為輸入元素,例如-示例–id屬性綁定到輸入控件,如下所示
                                  <input asp-for="Id" class="form-control" />

                                  Name屬性被綁定通過下面這種方式

                                  <input asp-for="Name" class="form-control" />
                                  模型綁定會把這些值綁定到Employee對象的屬性,將Employee對象傳遞給Create方法的參數,Create方法使用模型綁定技術獲取employee類型的參數值
                                  asp-for 是一個幫助標簽,你可以獲取到更多的關于內置幫助標簽在ASP.NET Core
                                  Post版本的Create方法調用Index視圖,將Employee對象作為Model傳遞給View,現在運行應用程序并且進入URL– /Home/Create,在表單中輸入所有值并點擊提交按鈕,我們會看到填充的值顯示在瀏覽器上

                                  下面2張圖片顯示了填充和提交的表單:

                                  6 復雜對象包含復雜對象

                                  EmployeeDetails.cs類包含了名稱為HomeAddress公共屬性,這個屬性是一個Address類型,因此復雜對象包含另一個復雜對象案例

                                  • public class Employee{ public int Id { get; set; } public string Name { get; set; } public DateTime DOB { get; set; } public Address HomeAddress { get; set; } public Role Role { get; set; }}public class Address{ public string HouseNumber { get; set; } public string Street { get; set; } public string City { get; set; } public string PostalCode { get; set; } public string Country { get; set; }}

                                    綁定HomeAddress屬性時,模型綁定處理過程和前面的相同:

                                    1 查找所有HomeAddress的公共屬性(即 HouseNumber, Street, City, PostalCode, Country)
                                    2 在表單數據中搜索這些公共屬性的值,注意路由&查詢字符串變量不能包含復雜類型

                                    更新Create.cshtml視圖文件綁定HomeAddress類型所有屬性,代碼如下:

                                    • @model Employee@{ ViewData["Title"]="Create Employee";}<h2>Create Employee</h2><form asp-action="Create" method="post"> <div class="form-group"> <label asp-for="Id"></label> <input asp-for="Id" class="form-control" /> </div> <div class="form-group"> <label asp-for="Name"></label> <input asp-for="Name" class="form-control" /> </div> <div class="form-group"> <label asp-for="DOB"></label> <input asp-for="DOB" class="form-control" /> </div> <div class="form-group"> <label asp-for="Role"></label> <select asp-for="Role" class="form-control" asp-items="@new SelectList(Enum.GetNames(typeof(Role)))"></select> </div> <div class="form-group"> <label asp-for="HomeAddress.HouseNumber"></label> <input asp-for="HomeAddress.HouseNumber" class="form-control" /> </div> <div class="form-group"> <label asp-for="HomeAddress.City"></label> <input asp-for="HomeAddress.City" class="form-control" /> </div> <div class="form-group"> <label asp-for="HomeAddress.Street"></label> <input asp-for="HomeAddress.Street" class="form-control" /> </div> <div class="form-group"> <label asp-for="HomeAddress.PostalCode"></label> <input asp-for="HomeAddress.PostalCode" class="form-control" /> </div> <div class="form-group"> <label asp-for="HomeAddress.Country"></label> <input asp-for="HomeAddress.Country" class="form-control" /> </div> <button type="submit" class="btn btn-primary">Submit</button></form>

                                      當綁定HomeAddress屬性時候,我們必須包含"HomeAddress",看Helper標簽asp-for="HomeAddress.HouseNumber" 綁定HouseNumber屬性,我們也為另一些屬性使用這種綁定

                                      編輯Index視圖顯示HomeAddress對象所有屬性,代碼如下:
                                      • @model Employee@{ ViewData["Title"]="Index";}
                                        <h2>Employee</h2>
                                        <table class="table table-sm table-bordered table-striped"> <tr><th>Id:</th><td>@Model.Id</td></tr> <tr><th>Name:</th><td>@Model.Name</td></tr> <tr><th>Date of Birth:</th><td>@Model.DOB.ToShortDateString()</td></tr> <tr><th>Role:</th><td>@Model.Role</td></tr> <tr><th>House No:</th><td>@Model.HomeAddress?.HouseNumber</td></tr> <tr><th>Street:</th><td>@Model.HomeAddress?.Street</td></tr> <tr><th>City:</th><td>@Model.HomeAddress?.City</td></tr> <tr><th>Postal Code:</th><td>@Model.HomeAddress?.PostalCode</td></tr> <tr><th>Country:</th><td>@Model.HomeAddress?.Country</td></tr></table>

                                        現在,運行應用程序并且進入URL– /Home/Create, 填充并提交表單,我們將發現address類型屬性的顯示,顯示圖片如下:

                                        檢查源代碼

                                        下面是瀏覽器為html生成的源代碼

                                        • <div class="form-group"> <label for="HomeAddress_HouseNumber">HouseNumber</label> <input class="form-control" type="text" id="HomeAddress_HouseNumber" name="HomeAddress.HouseNumber" value="" /></div><div class="form-group"> <label for="HomeAddress_City">City</label> <input class="form-control" type="text" id="HomeAddress_City" name="HomeAddress.City" value="" /></div><div class="form-group"> <label for="HomeAddress_Street">Street</label> <input class="form-control" type="text" id="HomeAddress_Street" name="HomeAddress.Street" value="" /></div><div class="form-group"> <label for="HomeAddress_PostalCode">PostalCode</label> <input class="form-control" type="text" id="HomeAddress_PostalCode" name="HomeAddress.PostalCode" value="" /></div><div class="form-group"> <label for="HomeAddress_Country">Country</label> <input class="form-control" type="text" id="HomeAddress_Country" name="HomeAddress.Country" value="" /></div>

                                          HouseNumber輸入控件獲取屬性名字的值HomeAddress.HouseNumber,然而id屬性的值變為HomeAddress_HouseNumber,相同的方式,City輸入控件獲取name屬性的值,然而id的屬性的值為 HomeAddress_City

                                          在C#代碼中我們也能獲取HouseNumber值在action 方法通過使用Request.Form方法,代碼如下:
                                          string houseNo=Request.Form["HomeAddress.HouseNumber"];
                                          針對另外一些值也是相同的方式
                                          7 使用[Bind(Prefix)]特性綁定復雜類型

                                          [Bind(Prefix)]特性能修改復雜類型模型綁定的默認行為,讓我們通過一個例子來理解,創建一個名為PersonAddress.cs的模型類使用下面代碼:

                                          • namespace AspNetCore.ModelBinding.Models{ public class PersonAddress { public string City { get; set; } public string Country { get; set; } }}
                                            接下來,在HomeController類中添加一個新的action方法叫DisplayPerson
                                            • [HttpPost]public IActionResult DisplayPerson(PersonAddress personAddress){ return View(personAddress);}

                                              下一步,修改Create視圖中asp-action標簽的值,將該值設置為DisplayPerson,代碼如下:

                                              • <form asp-action="DisplayPerson" method="post"> ...</form>
                                                現在,意味著當我們在表單中輸入數據并且提交表單時,數據將被提交到DisplayPerson方法 ,在Views->Home文件夾創建一個DisplayPerson視圖,這個視圖包含PersonAddress類型,并顯示城市和國家在模型對象
                                                DisplayPerson視圖代碼如下:
                                                • @model PersonAddress@{ ViewData["Title"]="Person";}<h2>Person</h2><table class="table table-sm table-bordered table-striped"> <tr><th>City:</th><td>@Model.City</td></tr> <tr><th>Country:</th><td>@Model.Country</td></tr></table>

                                                  現在運行你的應用程序,并且進入URL- /Home/Create,填充表單并且點擊提交按鈕

                                                  注意City和Country沒有包含任何值,模型綁定失敗了,看如下圖:

                                                  模型綁定失敗的原因是因為City和Country輸入控件屬性Name包含了字符串HomeAddress 前綴,在瀏覽器中檢查輸入控件源代碼

                                                <input class="form-control" type="text" id="HomeAddress_City" name="HomeAddress.City" value=""><input class="form-control" type="text" id="HomeAddress_Country" name="HomeAddress.Country" value="">

                                                為了解決這個問題,我們在action方法的參數中應用[Bind(Prefix)],告訴ASP.NET Core 基于HomeAddress前綴完成模型綁定

                                                因此改變DisplayPerson 方法包含[Bind(Prefix=nameof(Employee.HomeAddress))]顯示如下:
                                                • public IActionResult DisplayPerson([Bind(Prefix=nameof(Employee.HomeAddress))] PersonAddress personAddress){ return View(personAddress);}

                                                  再次提交表單,這次我們將發現City和Country值并將他們顯示在瀏覽器,看下面圖片:

                                                  使用[Bind]選擇性的綁定屬性

                                                  我們可以選擇性的綁定屬性,Bind()方法的第一個參數提供包含模型綁定中的所有屬性的名稱(用逗號分隔的列表中),那意味著剩下的屬性將不被綁定
                                                  修改DisplayPerson方法代碼,綁定方法包含City屬性
                                                  • public IActionResult DisplayPerson([Bind(nameof(PersonAddress.City), Prefix=nameof(Employee.HomeAddress))] PersonAddress personAddress){ return View(personAddress);}
                                                    測試一下該方法,你將看到僅僅City值顯示,如下圖所示:

                                                    我們可以使用另外一種方法實現相同的功能,在PersonAddress類的Country屬性上使用 [BindNever] 特性,BindNever指定的屬性模型綁定將被忽略

                                                    • using Microsoft.AspNetCore.Mvc.ModelBinding;namespace AspNetCore.ModelBinding.Models{ public class PersonAddress { public string City { get; set; } [BindNever] public string Country { get; set; } }}

                                                      8 模型綁定上傳文件

                                                      我們通過模型綁定技術完成上傳文件功能,這里我們必須做3件事情:

                                                      1 在View中添加input type=”file”控件

                                                      2 在html表單的標簽中添加enctype="multipart/form-data"特性

                                                      3 在action方法中添加IFormFile類型參數,使用該參數綁定上傳文件

                                                      我們創建一個上傳文件的特性,添加一個新的Controller并且命名為FileUploadController.cs. 代碼給與如下:

                                                      • using Microsoft.AspNetCore.Mvc;
                                                        namespace ModelBindingValidation.Controllers{ public class FileUploadController : Controller { private IWebHostEnvironment hostingEnvironment; public FileUploadController(IWebHostEnvironment environment) { hostingEnvironment=environment; } public IActionResult Index()=> View(); [HttpPost] public async Task<IActionResult> Index(IFormFile file) { string path=Path.Combine(hostingEnvironment.WebRootPath, "Images/" + file.FileName); using (var stream=new FileStream(path, FileMode.Create)) { await file.CopyToAsync(stream); } return View((object)"Success"); } }}

                                                        添加一個IWebHostEnvironment 的依賴用來獲取"wwwroot"文件夾的全部路徑, Index方法通過模型綁定技術將上傳的文件綁定到IFormFile類型參數

                                                        方法內部將文件保存到應用程序wwwroot/Images文件夾內

                                                        為了能夠正常工作你確保在wwwroot目錄下創建Images文件夾,接下來在 Views/FileUpload文件夾內添加Index文件,代碼如下:

                                                        • @model string@{ ViewData["Title"]="Upload File";}
                                                          <h2>Upload File</h2><h3>@Model</h3>
                                                          <form method="post" enctype="multipart/form-data"> <div class="form-group"> <input type="file" name="file" /> </div> <button type="submit" class="btn btn-primary">Submit</button></form>
                                                          瀏覽器看上如下:

                                                          總結:

                                                          在ASP.NET Core中模型綁定是一個重要的感念,開發人員能夠非常容易的在Views和Controllers之間傳輸數據,在這節文章中,我們通過例子來了解模型綁定原理
                                                          源代碼地址
                                                          https://github.com/bingbing-gui/Asp.Net-Core-Skill/tree/master/Fundamentals/AspNetCore.ModelBinding/AspNetCore.ModelBinding

                                                          參考文獻

                                                          https://www.yogihosting.com/aspnet-core-model-binding/

           AngularJS支持通過單個頁面上的多個視圖單頁應用。要做到這一點AngularJS提供了ng-view 、 ng-template 指令和 $routeProvider 服務。

            ng-view

            NG-view標記簡單地創建一個占位符,其中一個相應的視圖(HTML或ng-template視圖),可以根據配置來放置。

            使用

            定義主模塊使用一個 div 及ng-view。

          <div ng-app="mainApp">
          ...
             <div ng-view></div>
          
          </div>    12345復制代碼類型:[html]

            ng-template

            ng-template指令用于創建使用腳本標記的HTML視圖。它包含一個“id”屬性用于由 $routeProvider 映射帶有控制器的視圖。

            使用

            定義腳本塊類型為 ng-template 的主模塊 。

          div ng-app="mainApp">
          ...
             <script type="text/ng-template" id="addStudent.htm">
                <h2> Add Student </h2>
                   {{message}}
             </script>
          
          </div>    12345678復制代碼類型:[html]

            $routeProvider

            $routeProvider是用來設置URL配置的關鍵服務,映射與對應的HTML頁面或ng-template,并附加相同的控制器。

            使用

            定義腳本塊類型為 ng-template 的主模塊 。

          <div ng-app="mainApp">
          ...
             <script type="text/ng-template" id="addStudent.htm">
                <h2> Add Student </h2>
                   {{message}}
             </script>
          
          </div>    
          123456789復制代碼類型:[html]

            使用

            定義腳本塊及主模塊,并設置路由配置。

          var mainApp=angular.module("mainApp", ['ngRoute']);
                
                mainApp.config(['$routeProvider',
                   function($routeProvider) {
                      $routeProvider.
                         when('/addStudent', {
                            templateUrl: 'addStudent.htm',
                            controller: 'AddStudentController'
                         }).
                         when('/viewStudents', {
                            templateUrl: 'viewStudents.htm',
                            controller: 'ViewStudentsController'
                         }).
                         otherwise({
                            redirectTo: '/addStudent'
                         });
                   }]);
          123456789101112131415161718復制代碼類型:[html]

            以下是在上面的例子中要考慮的重點。

            $ routeProvider定義作為一個函數在mainApp模塊的配置下,使用鍵 '$routeProvider'.

            $routeProvider定義URL “/addStudent”,然后映射到“addStudent.htm”。addStudent.htm 存在于相同的路徑的主html頁面。如果HTM網頁沒有定義,那么NG-模板使用id="addStudent.htm"。我們使用ng-template。

            "otherwise" 用于設置的默認視圖。

            "controller" 用于為視圖設置相應的控制器。


          開課吧廣場-人才學習交流平臺

          網站開發一般基于瀏覽器來展示,手機端目前成為兵家必爭之地,怎么在網頁端開發一份代碼,在手機端也能有不錯的效果呢。查資料發現通過響應式布局和自適應布局可以解決,那接下來我們來實踐一下。

          概念:

          1、首先,響應式和自適應最為關鍵的區別是什么呢?

          簡而言之,響應式就相當于液體,它可以自動適應不同尺寸的屏幕,無論你的設備尺寸多么奇葩。響應式使用CSS media queries的方法,根據目標設備自動改變風格如顯示類型,寬度、高度等,這能很好解決不同屏幕尺寸的顯示問題。

          而自適應設計是基于斷點使用靜態布局,一旦頁面被加載就無法再進行自動適應,自適應會自動檢測屏幕的大小來加載適當的工作布局,也就是說,當你要采用自適應設計網站時,你得一個一個設計6種常見的屏幕布局。

          1.320

          2.480

          3.760

          4.960

          5.1200

          6.1600

          顯然,自適應設計需要做更多的工作,你必須至少設計6種常見的布局。而響應式設計可以更好地適應復雜的媒體設備要求,能很好地解決顯示和性能問題。

          千言萬語不如一圖:

          如何選擇屏幕大小分割點

          如何確定媒體查詢的分割點也是一個開發中會遇到的問題,下面是市場上的移動設備和電腦屏幕分辨率的分布情況,可以發現不同品牌和型號的設備屏幕分辨率一般都不一樣

          如果我們選擇600px,900px,1200px,1800px作為分割點,可以適配到常見的14個機型:

          當然這只是其中的一種分割方案,我們還可以這樣劃分:480px,800px,1400px,1400px

          簡單點:提供三個設計稿件尺寸分別是:640px、960px、1200px

          而作為曾經典型的響應式布局框架,Bootstrap是怎么進行斷點的呢?

          上面的分割方案不一定滿足項目中的實際需求,我們可以先用跨度大的分割點進行分割,如果出現不適配的情況可以再根據實際情況增加新的分割點。


          響應式設計的步驟

          1. 設置 Meta 標簽

          大多數移動瀏覽器將HTML頁面放大為寬的視圖(viewport)以符合屏幕分辨率。你可以使用視圖的meta標簽來進行重置。下面的視圖標簽告訴瀏覽器,使用設備的寬度作為視圖寬度并禁止初始的縮放。在<head>標簽里加入這個meta標簽。

          <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

          [1](user-scalable=no 屬性能夠解決 iPad 切換橫屏之后觸摸才能回到具體尺寸的問題。

          2. 通過媒介查詢來設置樣式 Media Queries

          Media Queries 是響應式設計的核心。 它根據條件告訴瀏覽器如何為指定視圖寬度渲染頁面。假如一個終端的分辨率小于 980px,那么可以這樣寫:

          @media screen and (max-width: 980px) {
            #head { … }
            #content { … }
            #footer { … }
          }

          這里的樣式就會覆蓋上面已經定義好的樣式。

          3. 設置多種視圖寬度

          假如我們要設定兼容 iPad 和 iPhone 的視圖,那么可以這樣設置:

          /** iPad **/
          @media only screen and (min-width: 768px) and (max-width: 1024px) {}
          /** iPhone **/
          @media only screen and (min-width: 320px) and (max-width: 767px) {}

          恩,差不多就這樣的一個原理。

          一些注意的

          1. 寬度需要使用百分比

          例如這樣:

          #head { width: 100% }
          #content { width: 50%; }

          2. 處理圖片縮放的方法

          • 簡單的解決方法可以使用百分比,但這樣不友好,會放大或者縮小圖片。那么可以嘗試給圖片指定的最大寬度為百分比。假如圖片超過了,就縮小。假如圖片小了,就原尺寸輸出。
          img { width: auto; max-width: 100%; }
          
          或
          img { max-width: 100%; height: auto }
          這行代碼對于大多數嵌入網頁的視頻也有效果,所以可以寫成:
          
          img object { max-width: 100%; height:auto}
          
          老版本的Ie不支持max-width,所以只好寫成:
          
          img { width: 100%; height:auto}
          
          此外,windows平臺縮放圖片時,可能出現圖像失真現象,這時可以嘗試使用IE的專有命令:
          Img { -ms-interpolation-mode: bicubic }
          • ::before::after偽元素 +content 屬性來動態顯示一些內容或者做其它很酷的事情,在 CSS3 中,任何元素都可以使用 content 屬性了,這個方法就是結合 css3 的 attr 屬性和 HTML 自定義屬性的功能: HTML 結構:
          <img src="image.jpg"
               data-src-600px="image-600px.jpg"
               data-src-800px="image-800px.jpg"
               alt="">

          CSS 控制:

          @media (min-device-width:600px) {
              img[data-src-600px] {
                  content: attr(data-src-600px, url);
              }
          }
          
          @media (min-device-width:800px) {
              img[data-src-800px] {
                  content: attr(data-src-800px, url);
              }
          }

          3. 其他屬性

          例如preiframevideo等,都需要和img一樣控制好寬度。對于table,建議不要增加 padding 屬性,低分辨率下使用內容居中:

          table th, table td { padding: 0 0; text-align: center; }


          來源資料:

          http://www.woshipm.com/pd/153425.html

          https://www.yisu.com/zixun/118775.html

          http://caibaojian.com/356.html

          https://juejin.cn/post/6844903814332432397(推薦)

          https://www.xiaoxili.com/blog/posts/fusion-web-design


          主站蜘蛛池模板: 精品人妻一区二区三区四区在线| 国产精品高清一区二区三区| 久久4k岛国高清一区二区| 国产一区在线电影| 日本丰满少妇一区二区三区 | 色窝窝免费一区二区三区| 美女视频黄a视频全免费网站一区 美女免费视频一区二区 | 五月婷婷一区二区| 精品国产一区二区三区久久影院 | 一区二区三区高清在线| 免费看一区二区三区四区| 中文字幕无码不卡一区二区三区| 国产免费一区二区三区VR| 亚洲AV综合色一区二区三区 | 亚洲午夜在线一区| 琪琪see色原网一区二区| 精品人无码一区二区三区| 亚洲中文字幕丝袜制服一区 | 亚洲色精品vr一区二区三区| 国产小仙女视频一区二区三区| 久久AAAA片一区二区| 国产情侣一区二区| 亚洲av无码一区二区三区不卡| 国产第一区二区三区在线观看| 消息称老熟妇乱视频一区二区| 免费无码AV一区二区| 一色一伦一区二区三区| 无码国产精品一区二区免费3p| 一区二区三区免费高清视频| 手机福利视频一区二区| 91久久精品一区二区| 国产伦理一区二区| 一区 二区 三区 中文字幕| 精品国产高清自在线一区二区三区 | 久久久久人妻一区精品性色av| 人妻少妇一区二区三区| 一区二区三区在线播放| 日韩精品电影一区亚洲| 天堂成人一区二区三区| 国产品无码一区二区三区在线| 精品乱码一区二区三区四区|