基礎(chǔ)VM

2019-04-04 17:40 更新

BaseVM是WTM框架中的基礎(chǔ)VM,框架中所有內(nèi)置的VM都繼承自它,同時(shí)框架要求開發(fā)者自定義的VM也都要繼承它


BaseVM提供了連接Controller與View之間的,讓開發(fā)者編寫邏輯的地方。如果需要對(duì)數(shù)據(jù)進(jìn)行增刪改查,導(dǎo)入導(dǎo)出等操作,請(qǐng)繼承更具體的VM
建立一個(gè)VM

建立一個(gè)基礎(chǔ)的VM非常簡(jiǎn)單,只需要繼承BaseVM就可以了,下面我們建立一個(gè)LoginVM來(lái)處理用戶登陸的操作

  1. using WalkingTec.Mvvm.Core;
  2. public class LoginVM : BaseVM{
  3. }

上面的代碼定義了一個(gè)LoginVM,它有什么用呢?

簡(jiǎn)單來(lái)說(shuō),當(dāng)你在Controller中通過CreateVM方法創(chuàng)建這個(gè)VM,框架會(huì)自動(dòng)將編寫邏輯需要的很多數(shù)據(jù)傳遞給VM,比如當(dāng)前登陸用戶的信息,表單提交的信息,當(dāng)前數(shù)據(jù)庫(kù)連接等等

同時(shí),VM里的屬性還可以用來(lái)綁定前臺(tái)頁(yè)面控件,這樣一個(gè)VM連接了前臺(tái),后臺(tái)和數(shù)據(jù)庫(kù),在VM里你可以訪問所有需要的信息來(lái)編寫你需要的邏輯

我們來(lái)完善一下LoginVM,來(lái)演示一個(gè)簡(jiǎn)單的登陸操作

  1. using WalkingTec.Mvvm.Core;
  2. public class LoginVM : BaseVM{
  3. [Display(Name = "賬號(hào)")]
  4. [Required(AllowEmptyStrings = false)]
  5. [StringLength(10)]
  6. public string Username { get; set; }
  7. [Display(Name = "密碼")]
  8. [Required(AllowEmptyStrings = false)]
  9. [StringLength(10,ErrorMessage ="{0}最多輸入{1}個(gè)字符")]
  10. public string Password { get; set; }
  11. public LoginUserInfo DoLogin()
  12. {
  13. //根據(jù)用戶名和密碼查詢用戶
  14. var user = DC.Set()
  15. .Where(x => x.ITCode.ToLower() == ITCode.ToLower() && x.Password.ToLower() == Password.ToLower() && x.IsValid == true)
  16. .SingleOrDefault();
  17. //如果沒有找到則輸出錯(cuò)誤
  18. if (user == null)
  19. {
  20. MSD.AddModelError("", "登錄失敗");
  21. }
  22. return user;
  23. }
  24. }
使用VM

我們把登陸的全部邏輯封裝在了LoginVM中,這樣在Controller里,我們的代碼就非常簡(jiǎn)單了

  1. using WalkingTec.Mvvm.Core;
  2. using WalkingTec.Mvvm.Mvc;
  3. [Public]
  4. public class LoginController : BaseController
  5. {
  6. [ActionDescription("登錄")]
  7. public IActionResult Login()
  8. {
  9. LoginVM vm = CreateVM();
  10. return View(vm);
  11. }
  12. [HttpPost]
  13. public ActionResult Login(LoginVM vm)
  14. {
  15. var user = vm.DoLogin();
  16. if (user == null)
  17. {
  18. return View(vm);
  19. }
  20. else
  21. {
  22. return Redirect("/home/index");
  23. }
  24. }
  25. }
BaseController是框架提供的Controller基類,所有應(yīng)用框架的Controller都應(yīng)該繼承這個(gè)類,詳見Controller部分的文檔
[Public],[ActionDescription]等屬性都是框架提供的應(yīng)用于Controller和Action上的屬性,詳見Controller部分的文檔
在Controller中使用CreateVM來(lái)初始化VM,這樣做可以把當(dāng)前請(qǐng)求的很多信息傳遞給VM,比如數(shù)據(jù)庫(kù)連接,Session等
VM的自定義驗(yàn)證

簡(jiǎn)單的單一字段驗(yàn)證可以通過在屬性上加Attribute的方式來(lái)實(shí)現(xiàn)

復(fù)雜的驗(yàn)證邏輯可以通過重寫B(tài)aseVM中的Validate方法來(lái)實(shí)現(xiàn)

下面的代碼演示了一個(gè)修改密碼的VM

  1. using System.Collections.Generic;
  2. using System.ComponentModel.DataAnnotations;
  3. using System.Linq;
  4. using WalkingTec.Mvvm.Core;
  5. namespace WalkingTec.Mvvm.Demo.ViewModels.HomeVMs
  6. {
  7. public class ChangePasswordVM : BaseVM
  8. {
  9. [Display(Name = "用戶名")]
  10. public string ITCode { get; set; }
  11. [Display(Name = "當(dāng)前密碼")]
  12. [Required(AllowEmptyStrings = false)]
  13. [StringLength(50, ErrorMessage = "{0}最多輸入{1}個(gè)字符")]
  14. public string OldPassword { get; set; }
  15. [Display(Name = "新密碼")]
  16. [Required(AllowEmptyStrings = false)]
  17. [StringLength(50, ErrorMessage = "{0}最多輸入{1}個(gè)字符")]
  18. public string NewPassword { get; set; }
  19. [Display(Name = "新密碼")]
  20. [Required(AllowEmptyStrings = false)]
  21. [StringLength(50, ErrorMessage = "{0}最多輸入{1}個(gè)字符")]
  22. public string NewPasswordComfirm { get; set; }
  23. public override void Validate()
  24. {
  25. //檢查原密碼是否正確,如不正確則輸出錯(cuò)誤
  26. if (DC.Set().Where(x => x.ITCode == LoginUserInfo.ITCode && x.Password == Utils.GetMD5String(OldPassword)).SingleOrDefault() == null){
  27. MSD.AddModelError("OldPassword", "當(dāng)前密碼錯(cuò)誤");
  28. }
  29. //檢查兩次新密碼是否輸入一致,如不一致則輸出錯(cuò)誤
  30. if (NewPassword != NewPasswordComfirm)
  31. {
  32. MSD.AddModelError("NewPasswordComfirm", "兩次新密碼輸入不一致");
  33. }
  34. }
  35. public void DoChange()
  36. {
  37. var user = DC.Set().Where(x => x.ITCode == LoginUserInfo.ITCode).SingleOrDefault();
  38. if (user != null)
  39. {
  40. user.Password = Utils.GetMD5String(NewPassword);
  41. }
  42. DC.SaveChanges();
  43. }
  44. }
  45. }
VM的初始化

重寫VM中的InitVM和ReInitVM方法,進(jìn)行VM需要初始化的變量和操作,之所以要將初始化的代碼放到這里,是因?yàn)橹挥性贗nitVM和ReInitVM之后,VM中的DataContext,Session,ModelState等才有值

InitVM是在CreateVM時(shí)調(diào)用,ReInitVM是在Post回來(lái)時(shí)模型驗(yàn)證出錯(cuò)的時(shí)候調(diào)用,如果沒有重寫ReInitVM方法,則會(huì)默認(rèn)調(diào)用InitVM方法

當(dāng)手工通過new的方式建立vm時(shí),需要手動(dòng)調(diào)用InitVM和/或ReInitVM,并使用CopyContext方法從其他VM中復(fù)制DataContext,Session,ModelState等值


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)