018_TemplateModel
1. 我們已經知道如何使用基本的Java類(Map, String,等)來構建數據模型了。在內部, 模板中可用的變量都是實現了freemarker.template.TemplateModel接口的Java對象。但在數據模型中, 可以使用基本的Java集合類作為變量, 因為這些變量會在內部被替換為適當的TemplateModel類型。這種功能特性被稱作是對象包裝。
2. 對象包裝功能可以透明地把任何類型的對象轉換為實現了TemplateModel接口類型的實例。
3. 包裝(轉換)這些對象, 需要使用合適的, 也就是所謂的對象包裝器實現。
4. 那么首先來熟悉一下TemplateModel接口
5. 有一個粗略的freemarker.template.TemplateModel子接口對應每種基本變量類型(TemplateHashModel對應哈希表, TemplateSequenceModel對應序列, TemplateNumberModel對應數字等等)。
6. 如果想嘗試自己的TemplateModel實現, 一個簡單的方式是創建它的實例, 然后將這個實例放入數據模型中(也就是把它放到哈希表的根root上)。對象包裝器將會給模板提供它的原狀, 因為它已經實現了TemplateModel接口, 所以沒有轉換(包裝)的需要。
7. 請注意一個類可以實現多個TemplateModel接口, 這就是為什么FTL變量可以有多種類型。
8. 有4種類型的標量: 布爾值, 數字, 字符串, 日期類型(子類型: 日期(沒有時間部分), 時間(沒有日期部分), 或者日期-時間)。
9. 每一種標量類型都是TemplateTypeModel接口的實現, 這里的Type就是類型的名稱。這些接口只定義了一個方法: type getAsType();。它返回變量的Java類型(boolean, Number, String和Date各自代表的值)。
10. 由于歷史遺留的原因, 字符串標量的接口是TemplateScalarModel, 而不是TemplateStringModel。(因為早期的FreeMarker字符串就是標量。)
11. freemarker.template.TemplateBooleanModel接口
12. freemarker.template.TemplateNumberModel接口
13. freemarker.template.TemplateScalarModel接口
14. freemarker.template.TemplateDateModel接口
15. 標量這些接口的一個細小的實現和SimpleType類名在freemarker.template包中是可用的。但是卻沒有SimpleBooleanModel類型; 為了代表布爾值, 可以使用TemplateBooleanModel.TRUE和TemplateBooleanModel.FALSE來單獨使用。
16. 由于歷史遺留的原因, 字符串標量的實現類是SimpleScalar, 而不是SimpleString。
17. TemplateBooleanModel.TRUE實際上是freemarker.template.TrueTemplateBooleanModel類
18. FalseTemplateBooleanModel實際上是freemarker.template.FalseTemplateBooleanModel類
19. freemarker.template.SimpleNumber實現類
20. freemarker.template.SimpleScalar實現類
21. freemarker.template.SimpleDate實現類
22. 在FTL中標量是一成不變的。當在模板中設置變量的值時, 使用其他的實例來替換TemplateTypeModel實例時, 是不用改變原來實例中存儲的值的。
23. 對于日期類型來說, 有一些難題, 因為Java API通常不區別java.util.Date只存儲日期部分(April 4, 2003), 時間部分(10:19:18 PM), 或兩者都存(April 4, 2003 10:19:18 PM)。為了用本文正確顯示值(或者進行其它確定的操作), FreeMarker必須知道java.util.Date的哪個部分存儲了有意義上的信息, 哪部分沒有被使用(通常是標記為0的)。不幸的是, 通常該信息只是當值從數據庫中取得時可用, 因為大多數數據庫有獨立的日期, 時間和日期-時間(又叫做時間戳)類型, java.sql有3個對應的java.util.Date子類和它們相匹配。
24. TemplateDateModel接口有兩個方法: 分別是java.util.Date getAsDate()和int getDateType()。該接口典型的實現是存儲一個java.util.Date對象, 加上一個整數來辨別子類型。這個整數的值也必須是TemplateDateModel接口中的常量之一: DATE, TIME, DATETIME和UNKNOWN。
25. 如果對象包裝器要包裝java.util.Date類, 它不是java.sql日期類的實例, 那就不能決定子類型是什么, 所以使用UNKNOWN。之后, 如果模板需要使用這個變量, ?而且操作也需要子類型, 那就會停止執行并拋出錯誤。為了避免這種情況的發生, 對于那些可能有問題的變量, 模板開發人員必須明確地指定子類型, 使用內建函數date, time或datetime(比如: lastUpdated?datetime)。請注意, 如果和格式化參數一起使用內建函數string, 比如: foo?string("MM/dd/yyyy"), 那么FreeMarker就不必知道子類型了。
26. 容器包括哈希表, 序列和集合三種類型。
27. 哈希表是實現了TemplateHashModel接口的Java對象。TemplateHashModel有兩個方法: TemplateModel get(String key), 這個方法根據給定的名稱返回子變量, boolean isEmpty(), 這個方法表明哈希表是否含有子變量。get方法當在給定的名稱沒有找到子變量時返回null。
28. TemplateHashModelEx接口擴展了TemplateHashModel。它增加了更多的方法, 使得可以使用內建函數values和keys來枚舉哈希表中的子變量。
29. 經常使用的實現類是SimpleHash, 該類實現了TemplateHashModelEx接口。從內部來說, 它使用一個java.util.Hash類型的對象存儲子變量。
30. 序列是實現了TemplateSequenceModel接口的Java對象。它包含兩個方法: TemplateModel get(int index)和int size()。
31. 經常使用的實現類是SimpleSequence。該類內部使用一個java.util.List類型的對象存儲它的子變量。SimpleSequence有添加子元素的方法。序列創建之后應該使用這些方法來填充序列。
32. 集合是實現了TemplateCollectionModel接口的Java對象。這個接口定義了一個方法: TemplateModelIterator iterator()。TemplateModelIterator接口和java.util.Iterator 相似, 但是它返回TemplateModelIterator而不是Object, 而且它能拋出TemplateModelException異常。
33. 通常使用的實現類是SimpleCollection。
?
總結
以上是生活随笔為你收集整理的018_TemplateModel的全部內容,希望文章能夠幫你解決所遇到的問題。