3. Các đối tượng ADO.Net:
3.3. Các điều khiển dữ liệu ASP.Net
3.3.1. Giới thiệu các điều khiển dữ liệu
ASP.NET 2.0 cung cấp một vài kiểu điều khiển Data Source Controls làm việc
tương thích với các kiểu Data Sources khác nhau, chúng bao gồm:
+ Điều khiển SqlDataSource control cho phép connections đến hầu hết các CSDL quan hệ.Providermặc định là cho CSDL SQL Server, ngoài ra còn cho Oracle, OLEDB,.v.v…
+ Điều khiển AccessDataSource control là trường hợp đặc biệt của điều khiển SqlDataSource control chứa provider được tối ưu cho CSDL Microsoft Access.
+ Điều khiển XMLDataSource control cho phép connection tới XML sources. + Điều khiển SiteMapDataSource control là mẫu được thiết kế riêng cho điều khiển XMLDataSource control.
+ Điều khiển ObjectDataSource control connects tới các đối tượng business.
* Giới thiệu Data-Bound Controls
Data-bound controls là các điều khiển buộc dữ liệu, cung cấp kết nối giữa các
điều khiển data source controls với người sử dụng. Chúng có thể được phân loại theo cách hiển thị như sau:
+ Tabular Controls: Là các điều khiển hiển thị một danh sách dữ liệu của các
bản ghi, gồm các điều khiển GridView, DataList, Repeater .v.v…
+ Single Record Display Controls: Như các điều khiển DetailsView, và FormView hiển thị từng bản ghi ở tại mỗi thời điểm.
+ Selection List Controls: Là điều khiển cho phép người sử dụng lựa chọn. Có 2 điều khiển hiển thị một trường dữ liệu đó là ListBox controls và DropDownList controls.
+ Tree Controls: Là các điều khiển dữ liệu lưu trữ trên các nút.
3.3.2. Data Binding Expression
ASP.NET buộc dữ liệu thông thường qua các khai báo hoặc qua các biểu thức buộc dữ liệu inline. Các biểu thức buộc dữ liệu (Data Binding Expressions) được khai báo trong cặp <%# ... %>
Các phương thức Eval() và Bind() được sử dụng để buộc các biểu thức với các điều khiển. Các biểu thức buộc dữ liệu được giải quyết khi phương thức DataBind() của các điều khiển được gọi trong file Code Behind. Thường thì phương thức này được gọi trong sự kiện Page_Load. Các điều khiển ASP.NET nhe GridView, DetailView, FormView, … gọi phương thức DataBind() để thực thi kết nối khi chúng
được buộc vào một điều khiển Data Sourcce.
Biểu thức Mô tả
<%# Eval("PropertyName") %> Dùng định nghĩa cách liên kết dữ liệu chỉ đọc. Ví dụ: xuất dữ liệu ra Label.
<%# Bind("PropertyName") %> Dùng định nghĩa cách liên kết dữ liệu đọc ghi (cập nhật dữ liệu). Ví dụ: xuất dữ liệu ra TextBox, …
Ví dụ:
<asp:FormView ID="FormView1"runat="server"AllowPaging="True" DataKeyNames="CustomerID"
DataSourceID="SqlDataSource1"> <EditItemTemplate>
CustomerName:
<asp:TextBoxID="txtCustName"runat="server"Text='<%# Bind("CName") %>'>
</asp:TextBox> </EditItemTemplate> <ItemTemplate> CustID:
<asp:Label ID="lblCustID"runat="server"Text='<%# Eval("CID") %>'>
</asp:Label> </ItemTemplate> </asp:FormView>
3.3.3. Giới thiệu điều khiển Data Bound
Data-bound controls là các điều khiển buộc dữ liệu, cung cấp kết nối giữa các
điều khiển data source controls với người sử dụng.
Điều khiển GridView:
Điều khiển Grid View là điều khiển phát triển từ điều khiển Data Grid (ASP.NET 1.0). Giống như DataGrid, GridView được sử dụng để hiển thị dữ liệu như một bảng dữ liệu. Sử dụng GridView để hiển thị, edit, delete, sort, và phân trang.
GridView và DataGrid có thể buộc vào một điều khiển DataSourceControl, nhưng DataGrid chỉ cho chọn dữ liệu. Việc Sort, paging, updates, và delete phải được code bằng tay. GridView hỗ t rợ thuộc tính DataSourceID làm cho điều khiển có thể tích hợp được các khả năng sorting, paging, updating, và deleting của điều khiển data source.
Ví dụ 3.4. Sử dụng GridView để hiển thị dữ liệu, sorting và paging (vidu3_5.aspx)
<%@PageLanguage="VB"%> <scriptrunat="server"></script> <body>
<formid="form1"runat="server">
<asp:SqlDataSourceID="SqlDataSource1"runat="server" ConnectionString="<%$ ConnectionStrings:MyConn %>" SelectCommand="SELECT [ProductID], [ProductType], [ProductName], [ProductDescription], [ProductSize], [ProductImageURL], [UnitPrice] FROM [Products]"> </asp:SqlDataSource>
<asp:GridViewID="MyGridView"runat="server"AllowPaging="True" AllowSorting="True"AutoGenerateColumns="False"PageSize="2" DataSourceID="SqlDataSource1"DataKeyNames="ProductID"> <Columns>
<asp:BoundFieldDataField="ProductID"HeaderText="ProductID" SortExpression="ProductID"/>
<asp:BoundFieldDataField="ProductType"HeaderText="ProductType"/> <asp:BoundFieldDataField="ProductName"HeaderText="ProductName" /> <asp:BoundFieldDataField="ProductDescription"
HeaderText="ProductDescription" />
<asp:BoundFieldDataField="ProductSize"HeaderText="ProductSize" /> <asp:BoundFieldDataField="UnitPrice"HeaderText="UnitPrice" /> <asp:TemplateFieldHeaderText="Image">
<ItemTemplate>
Eval("ProductImageURL")%>'/> </ItemTemplate>
</asp:TemplateField> </Columns>
<PagerSettingsFirstPageText="First"LastPageText="Last" PageButtonCount="4"Position="TopAndBottom" FirstPageImageUrl="~/Images/btnFirst.gif" LastPageImageUrl="~/Images/btnLast.gif" NextPageImageUrl="~/Images/btn_next.gif"NextPageText="Next" PreviousPageImageUrl="~/Images/btn_previous.gif" PreviousPageText="Previous" /> </asp:GridView> </form> </body>
Ta thực hiện thiết kế trong tab Design của cửa sổ Web Page Designer:
- Kéo điều khiển GridView vào cửa sổ thiết kế. Sau đó mở Smart Task và chọn: DataSource, Paging để phân trang và Sorting dùng để sắp xếp dữ liệu (Hình 3.8).
- Chọn Add New Column để thêm một cột thể hiện hình ảnh các sản phẩm. Xuất hiện hình 3.9. Chọn kiểu trường là TemplateFile và Header Text là Image. Sau
đó click OK.
- Chọn Edit Template và chọn Template vừa tạo để hiệu chỉnh xuất hiện cửa sổ
hình 3.10. Trong cửa sổ này ta thêm thẻ <Image> và buộc điều khiển này vào trường ProductImageURL
- Thực hiện phân trang hiển thị. Trong cửa sổ Properties mở rộng thuộc tính PagerSetting và Page size để định dạng phân trang (hình 3.11):
+ Mode: Kiểu duyệt trang (NextPreviousFirstLast, Numeric, NextPrevious, NumericFirstLast).
+ NextPageImagerURL: Địa chỉ ảnh của nút Next. + NextPageText: Chuỗi Text của nút Next
Tương tự cho các nút còn lại,… + Pagesize: Số bản ghi trên một trang
Kết quả duyệt ví dụ 3.4 trong hình 3.12.
Hình 3.9.Cửa sổ Add File
Hình 3.11.Cửa sổ Properties
Hình 3.12.Duyệt ví dụ 3.4.
Là các điều khiển mà toàn bộ thông tin của bản ghi sẽ được hiển thị trên một cell. Điểm khác nhau giữa hai điều khiển này là DataList có định dạng và template
mặc định còn Repeater không có mà phải tự thiết kế. Cách tạo DataList tương tự như
GridView.
Ví dụ 3.5.Sử dụng điều khiển DataList (vidu3_6.aspx) <%@PageLanguage="VB"%>
<scriptrunat="server"> </script>
<body>
<formid="form1"runat="server">
<asp:SqlDataSourceID="SqlDataSource1"runat="server"ConnectionString="<%$ ConnectionStrings:MyConn %>" SelectCommand="SELECT [ProductID], [ProductType], [ProductName], [ProductDescription], [ProductSize], [ProductImageURL], [UnitPrice] FROM [Products]">
</asp:SqlDataSource>
<asp:DataListID="DataList1" runat="server"DataSourceID="SqlDataSource1" RepeatColumns="2">
<ItemTemplate>
<asp:ImageID="Image1"runat="server"
ImageUrl='<%# Eval("ProductImageURL") %>' /><br/> Mãsản phẩm:
<asp:LabelID="ProductIDLabel"runat="server"
Text='<%# Eval("ProductID") %>'></asp:Label><br/> Tênsản phẩm:
<asp:LabelID="ProductNameLabel"runat="server"Text='<%# Eval("ProductName") %>'></asp:Label><br/>
Kiểusản phầm:
<asp:LabelID="ProductTypeLabel"runat="server"
Text='<%# Eval("ProductType")%>'></asp:Label><br/> Mô tả:
<asp:LabelID="ProductDescriptionLabel"runat="server"Text='<%# Eval("ProductDescription") %>'></asp:Label>
Kích thước sản phẩm:
<asp:LabelID="ProductSizeLabel"runat="server"
Text='<%# Eval("ProductSize")%>'></asp:Label><br/> Giásản phẩm (USD):
<asp:LabelID="UnitPriceLabel"runat="server"
Text='<%# Eval("UnitPrice") %>'></asp:Label><br/> </ItemTemplate>
</asp:DataList> </form>
</body>
Hình 3.13.Duyệt ví dụ 3.5.
Ví dụ 3.6.Sử dụng điều khiển Repeater (vidu3_7.aspx) <%@PageLanguage="VB"%>
<formid="form1"runat="server">
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:MyConn %>"
SelectCommand="SELECT [ProductID], [ProductType], [ProductName], [ProductDescription], [ProductSize], [ProductImageURL], [UnitPrice] FROM [Products]"> </asp:SqlDataSource>
<asp:RepeaterID="Repeater1" runat="server"DataSourceID="SqlDataSource1"> <ItemTemplate>
<asp:ImageID="Image1"runat="server"
ImageUrl='<%# Eval("ProductImageURL") %>' /><br/> Mãsản phẩm:
<asp:LabelID="ProductIDLabel"runat="server"
Text='<%# Eval("ProductID") %>'></asp:Label><br/> Tênsản phẩm:
<asp:LabelID="ProductNameLabel"runat="server"Text='<%# Eval("ProductName") %>'></asp:Label><br/>
Kiểusản phầm:
<asp:LabelID="ProductTypeLabel"runat="server"
Text='<%# Eval("ProductType")%>'></asp:Label><br/> Mô tả:
<asp:Label ID="ProductDescriptionLabel"runat="server"Text='<%# Eval("ProductDescription") %>'></asp:Label>
Kích thước sản phẩm:
<asp:LabelID="ProductSizeLabel"runat="server"
Text='<%# Eval("ProductSize")%>'></asp:Label><br/> Giásản phẩm (USD):
<asp:LabelID="UnitPriceLabel"runat="server"
Text='<%# Eval("UnitPrice") %>'></asp:Label><br/> </ItemTemplate>
</asp:Repeater> </form>
Kết quả triệu gọi ví dụ 3.6. cho trong hình 3.14.
Hình 3.14.Duyệt ví dụ 3.6.
Điều khiển DetailsView và FormView Controls:
Đây là hai điều khiển buộc dữ liệu, tại một thời điểm chỉ hiển thị một bản ghi. Khi buộc dữ liệu, điều khiển DetailsView tự động tạo các template, FormView chỉ tạo ra thẻ trắng và người thiết kế phải tự thiết kế các template.
Ví dụ 3.8. Minh họa việc sử dụng kết hợp điều khiển GridView và điều khiển DetailView. Điều khiển GridView hiển thị danh sách các sản phẩm còn điều khiển DetailView hiển thị thông tin chi tiết sản phẩm mà người dùng chọn trên điều khiển GridView.
<%@PageLanguage="VB"%> <formid="form1"runat="server">
<asp:SqlDataSourceID="SqlDataSource1"runat="server"
ConnectionString="<%$ ConnectionStrings:MyConn %>"
SelectCommand="SELECT [ProductID], [ProductType], [ProductName], [UnitPrice] FROM [Products]">
</asp:SqlDataSource>
<asp:GridView ID="GridView1" runat="server"AutoGenerateColumns="False" DataSourceID="SqlDataSource1"AllowPaging="True"BackColor="White" BorderColor="#E7E7FF"BorderStyle="None"BorderWidth="1px"
CellPadding="3"DataKeyNames="ProductID" PageSize="5" GridLines="Horizontal">
<Columns>
<asp:CommandFieldShowSelectButton="True"ButtonType="Image" SelectImageUrl="~/Images/dn.gif" />
SortExpression="ProductID" /> <asp:BoundFieldDataField="ProductType"
HeaderText="Kiểusản phẩm"SortExpression="ProductType"/> <asp:BoundFieldDataField="ProductName"
HeaderText="Tênsản phẩm"SortExpression="ProductName"/> <asp:BoundFieldDataField="UnitPrice"
HeaderText="Giá(USD)"SortExpression="UnitPrice" /> </Columns>
<PagerSettingsPageButtonCount="4" />
<FooterStyleBackColor="#B5C7DE"ForeColor="#4A3C8C" /> <RowStyleBackColor="#E7E7FF"ForeColor="#4A3C8C" />
<SelectedRowStyle BackColor="#738A9C" Font- Bold="True"ForeColor="#F7F7F7"/>
<PagerStyleBackColor="#E7E7FF"ForeColor="#4A3C8C" HorizontalAlign="Right"/>
<HeaderStyleBackColor="#4A3C8C"Font-Bold="True"ForeColor="#F7F7F7" /> <AlternatingRowStyleBackColor="#F7F7F7"/>
</asp:GridView>
<asp:SqlDataSourceID="SqlDataSource2"runat="server"ConnectionString="<%$ ConnectionStrings:MyConn %>" SelectCommand="SELECT [ProductID], [ProductType], [ProductName], [ProductDescription], [ProductSize],
[ProductImageURL], [UnitPrice] FROM [Products] WHERE ([ProductID] = @ProductID)">
<SelectParameters>
<asp:ControlParameterControlID="GridView1"DefaultValue="2"
Name="ProductID"PropertyName="SelectedValue"Type="Int32" /> </SelectParameters>
</asp:SqlDataSource> Thông tin chi tiết<br/>
<asp:DetailsViewID="DetailsView1"runat="server"AutoGenerateRows="False" BackColor="White"BorderColor="#E7E7FF"BorderStyle="None"
BorderWidth="1px"CellPadding="3"DataSourceID="SqlDataSource2" GridLines="Horizontal"Height="50px"Width="440px">
<PagerSettingsPageButtonCount="4" />
<FooterStyleBackColor="#B5C7DE" ForeColor="#4A3C8C" />
<EditRowStyleBackColor="#738A9C"Font-Bold="True"ForeColor="#F7F7F7" /> <RowStyleBackColor="#E7E7FF"ForeColor="#4A3C8C" />
<PagerStyleBackColor="#E7E7FF"ForeColor="#4A3C8C" HorizontalAlign="Right"/>
<Fields>
<asp:TemplateFieldHeaderText="Ảnh"> <ItemTemplate>
<asp:Image ID="Image1"runat="server"ImageUrl='<%# Eval("ProductImageURL") %>' />
</ItemTemplate> </asp:TemplateField>
<asp:BoundFieldDataField="ProductName"HeaderText="Tênsản phẩm"SortExpression="ProductName" />
<asp:BoundFieldDataField="ProductID"HeaderText="Mãsản phẩm" SortExpression="ProductID" />
<asp:BoundFieldDataField="ProductType"HeaderText="Kiểusản phẩm" SortExpression="ProductType" />
<asp:BoundFieldDataField="ProductDescription"HeaderText="Mô tả:"/> <asp:BoundFieldDataField="ProductSize"HeaderText="Kích thước"
SortExpression="ProductSize" />
<asp:BoundFieldDataField="UnitPrice"HeaderText="Đơn giá:" /> </Fields>
<HeaderStyleBackColor="#4A3C8C"Font-Bold="True"ForeColor="#F7F7F7" /> <AlternatingRowStyleBackColor="#F7F7F7" />
</asp:DetailsView> </form>
Chú ý: Xây dựng mệnh đề Where cho điều khiển SqlDataSource2 để kết nối
dữ liệu giữa hai điều khiển như hình 3.14.
Kết quả duyệt ví dụ 3.8. cho trong hình 3.15.
Hình 3.15.Duyệt ví dụ3.8.
3.3.4. Giới thiệu điều khiển Data Sources
Điều khiển SqlDataSource control: Ta sử dụng điều khiển SqlDataSource controltheo các bước cơ bản sau:
- Trong cửa sổ thiết kế trang Design View, kéo điều khiển
SqlDataSource controlvào vùng thiết kế (hình 3.16).
Hình 3.16.Cửa sổ thiết kế Web Page Designer
- Mở smart task panel và click Configure Data Source. Xuất hiện cửa sổ
Hình 3.17.Cửa sổ Choose your Data connection
- Trong cửa sổ Cửa sổ Add connection (hình 3.17) ta nhập các thông tin
kết nối và click OK để quay về cửa sổ 3.16 và chọn Next để tiếp tục.
Hình 3.18 Cửa sổ Add connection
- Trong cửa sổ Save connection string to the Application Configuration file (hình 3.19). Cho phép có lựa chọn save chuỗi kết nối này trong file web config hay không?
Hình 3.19.Cửa sổ Save connection string
- Trong cửa sổ Configure the Select Statement (hình 3.20) ta chọn các trường cho câu lệnh Select. Chú ý, trong cửa sổ này có các nút Where để thiết lập cho mệnh
đề Where cho câu lệnh Select (hình 3.21); nút Order By để sắp xếp dữ liệu.
Hình 3.20.Cửa sổ Configure the Select Statement
- Chọn Next, xuất hiện cửa sổ Test Query (hình 3.22) để Test truy vấn vừa tạo.
Hình 3.21.Cửa sổ thiết lập cho mệnh đềWhere. - Chọn Finsh để kết thúc.
Hình 3.22.Cửa sổ Test Query. Các bước trên tương ứng với khai báo thẻ như sau: <asp:SqlDataSourceID=”SqlDataSource1” runat=”server”
ConnectionString=”<%$ ConnectionStrings:MyConn %>”
SelectCommand=”SELECT [ProductID], [ProductType], [ProductName], [ProductDescription], [ProductSize], [ProductImageURL], [UnitPrice] FROM [Products]”>
</asp:SqlDataSource>
Chuỗi kết nối được khai báo trong tệp web config như sau: <connectionStrings>
<addname=”MyConn”connectionString=”Data Source=.;Initial Catalog=QLBanHang;User ID=sa;Password=12102006” providerName=”System.Data.SqlClient”/>
</connectionStrings>
Chú ý:
- Khi không Save chuỗi kết nối trong tệp web config thì chuỗi kết nối đó sẽ được khai báo tường minh trong source như sau.
- Trong lập trình người ta thường kết hợp hai cách thiết kế: Dùng chỉ dẫn của Design View sau đó chuyển sang Source để hiệu chỉnh lại.
<asp:SqlDataSourceID="SqlDataSource1"runat="server"
ConnectionString="Data Source=.;Initial Catalog=QLBanHang;User ID=sa;Password=12102006"ProviderName="System.Data.SqlClient" SelectCommand="SELECT [ProductID], [ProductType], [ProductName], [ProductDescription], [ProductSize], [ProductImageURL], [UnitPrice] FROM [Products]">
</asp:SqlDataSource>
3.3.5. Các thao tác dữ liệu với Data Controls
a) Giới thiệu các thao tác ghi dữ liệu
Không phải tất cả các điều khiển dữ liệu đều hỗ trợ cho việc ghi dữ liệu. Đối
với các điều khiển data source controls, tất cả đều support cho việc ghi dữ liệu trừ điều khiển SiteMapDataSource.
Nhưng giữa các điều khiển buộc dữ liệu (data-binding controls) còn có khá nhiều các hạn chế. Các điều khiển chọn danh sách dữ liệu (DropDownList và ListBox) không support cho việc ghi dữ liệu. Các điều khiển buộc dữ liệu trong phiên
bản mới ASP.NET 2.0 support cung cấp các phương thức tốt nhất cho việc ghi dữ
liệu là: GridView, DetailsView, và FormView.
Tuy nhiên, GridView chỉ có thể update các bản ghi đã tồn tại, không tạo mới
bản ghi đã tồn tại, không tạo mới các bản ghi. DataList và Repeater có thể sử dụng cho việc ghi dữ liệu, nhưng chúng là các điều khiển trong các phiên bản cũ nên trong
một số trường chúng ta phải sử dụng các công nghệ cũ trong ASP.NET 1.1.
b) Updating các bản ghi
Trước khi đi vào các thao tác ghi dữ liệu ta xét thuộc tính DataKeyNames của
điều khiển buộc dữ liệu liên quan đến các thao tác đó.
Thuộc tínhDataKeyNames:
Tại cùng một thời điểm ta có thể có cùng một vài kiểu ghi dữ liệu cho một trường, do đó Visual Web Developer thêm thuộc tính DataKeyNamescho điều khiển buộc dữ liệu với mục đích giữ cả hai giá trị cũ và mới của một trường nào đó làm cho việc ghi dữ liệu được thực hiện một cách chính xác.
Để hiểu vai trò của thuộc tính DataKeyNames, ta hình dung trong hệ thống web site có một bảng ghi thông tin các ý kiến phản hổi từ khách hàng gọi là Comments. Trong bảng ta có một trường đầu tiên là trường kiểu số CommentsID nhận giá trị
duy nhất cho mỗi dòng. Khách hàng sẽ gửi các ý kiến kiến phản hồi của mình và được
lưu trong bảng. Đến một lúc nào đó các thông tin được sắp xếp lộn xộn và nhà quản trị
phải thay đổi các ID cho các ý kiến đó, ví dụ từ 20 chuyển sang 19. Để làm điều này, người quản trị sẽ chọn bản ghi muốn thay đổi (chẳng hạn dùng điều khiển Grid view) và ASP.NET 2.0 sẽ lưu giá trị ID đó vào một tham số. Người quản trị sẽ gửi câu lệnh như sau đến database:
UPDATECommentsSETComment =19WHEREComment =@CommentID
Lưu ý là trong câu lệnh trên tên trường đã thay đổi (CommentsID) để câu lệnh nhận dạng bản ghi cần thay đổi giá trị. Đúng ra phải là WHERE CommentsID=@CommentsID nhưng sẽ bị xảy ra xung đột bởi vì @CommentsID nhận hai giá trị: Một giá trị cũ được lưu trên GridView (giá trị 20) và
một giá trị mới do người quản trị nhập vào (19).
DataKeyNames giải quyết vấn đề này bằng cách tạo một từ điển giữ hai giá trị
này cho các trường trong danh sách của chúng: Một giá trị cũ và một giá trị mới. Khi câu lệnh được gửi đến Database, ASP.NET sử dụng khả năng thông minh của mình để
cung cấp giá trị mới từ DataKeyNames cho mệnh đề SET của câu lệnh và sử dụng giá trị cũ từ DataKeyNames cho mệnh của câu lệnh.
Thật là lãng phí và chậm khi load up từ điển DataKeyNames với mọi trường, đặc biệt là bởi vì hầu hết các trường không gây ra sự xung đột như trên. Visual Web Developer tự động adds các trường mà cấu trúc của nó duy nhất trong database.
Ta sử dụng thuộc tính DataKeyNames để thiết lập một danh sách các trường (cách nhau bởi dấu phẩy) thể hiện khóa chính của data source. Khi thuộc tính
DataKeyNames được thiết lập thì các điều khiển buộc dữ liệu (DetailsView, FormView, GridView) tự động tạo đối tượng DataKey thể hiện trường hoặc các trường khóa của bản ghi hiện tại và lưu trữ trong thuộc tính DataKey của nó. Khi thuộc tính AutoGenerateColumns của các đối tượng buộc dữ liệu thiết lập là True thì các trường chỉ định trong DataKeyNames tự động thiết lập là Read Only.
Chú ý: Ta phải thiết lập cho thuộc tính DataKeyNames cho các thao tác tự động Update, Delete và Insert cho điều khiển DetailsView và FormView; Update và Delete cho điều khiển GridView.
Thực hiện Update dữ liệu: