SpEL調用類的靜態成員統一控制前後端的數據字典名稱

這次是事兒B地想要統一控制前後端的數據字典名稱。

在做後臺管理系統時,通常會遇見很多數據字典。例如,學生的性別(男/女)、政治面貌(黨員/團員/羣衆)等。在新增和編輯時,這類字段通常以下拉列表的形式呈現;而下拉列表的內容可以直接在後端查詢並使用模板引擎渲染,也可以異步查詢、JS動態渲染。

@Controller
@RequestMapping("/student")
public class StudentController {

    @Autowired
    private StudentService studentService;
    @Autowired
    private DictionaryService dictionaryService;
    
    @GetMapping("/view/{id}")
    public String view(@PathVariable Integer id) {
        model.addAttribute("student", studentService.getById(id));
        
        model.addAttribute("sexes", dictionaryService.findItemsBy("sex"));
        model.addAttribute("politics", dictionaryService.findItemsBy("politic"));
    }
    
}

上述代碼是在請求頁面時就查詢字典項,利用模板引擎渲染完畢之後再返回給前端。這裏存在一個問題:如果字典sex有很多地方用到了,某天我決定給他換個名稱(比如xingbie),那就得一處一處地改代碼。於是我將所有字典名稱寫在一個接口類中:

public interface AppConstant {
    
    String DICT_SEX = "sex";
    String DICT_POLITIC = "politic";
    
}

所有代碼都通過接口類來選擇字典:

@GetMapping("/view/{id}")
public String view(@PathVariable Integer id) {
    model.addAttribute("student", studentService.getById(id));
    
    model.addAttribute(AppConstant.DICT_SEX + "es", dictionaryService.findItemsBy(AppConstant.DICT_SEX));
    model.addAttribute(AppConstant.DICT_POLITIC + "s", dictionaryService.findItemsBy(AppConstant.DICT_POLITIC));
}

這樣,當字典名稱發生變更時,只需要修改一處即可。

但問題又來了,後端的字典名稱統一了,傳給前端的字典名稱依舊是千變萬化,前端被迫將字典名稱寫死在代碼中:

<!-- Thymeleaf -->
<select class="form-control" id="sex" readonly>
    <!-- student.sex爲整型:0-男,1-女 -->
    <option th:each="e : ${sexes}" th:text="${e.val}" th:selected="${e.name eq (student.sex + '')}"></option>
</select>

考慮到JSP能夠直接調用Java類的靜態成員,SpEL也提供了類似的功能:T(com.xx.xx.AppConstant).DICT_SEX。然後我將所有字典以Map<String, List<DictionaryItem>>的形式打包後再傳給前端,通過SpEL的map[KEY]獲取對應的字典:

<!-- Thymeleaf -->
<select class="form-control" id="sex" readonly>
    <option th:each="e : ${dictionaryTable[T(com.xx.AppConstant).DICT_SEX + 'es']}"
            th:text="${e.val}"
            th:selected="${e.name eq (student.sex + '')}"></option>
</select>

最初,我是想直接使用${T(com.xx.xx.AppConstant).DICT_SEX}等價${sex}獲取後端傳遞過來的sex參數,但發現前者實際上就是一個字符串。所以變通了一下,將其作爲鍵名,將字典打包成Map

發佈了4 篇原創文章 · 獲贊 8 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章