DynamicDSL將遵循以下的交互展示邏輯: 描述文件(XML,Widget) --->(綁定數據)--->渲染模板--->渲染--->事件驅動--->數據改變 這樣循環下來的,最終我們看到的就是App上的界面與交互效果了。
這看上去和RN,flutter有點像,只是我們這個是特定場景的使用。
實現了AST節點,已經有了動態計算數據的能力,接下來我們將實現動態XML模板的綁定,為渲染前生成布局描述模板。
<View>
<View text="年齡: {{ 33.22 * 2}}" color="{{ item[age] >= 20 ? '#FFFFFF' : '#DDDDDD' }}" />
class="hljs-name"View>
這個模板比較簡單,它有一個根節點,根節點有一個子節點包含兩個屬性,我們用"{{ }}"來描述需要計算的表達式,如果沒有兩個大括號則認為是原始字符串。
「這里我們規定,布局模板必須在一個根節點下面!」
XML原始節點展示如下:
text節點可以直接計算出結果, color節點通過獲取環境變量中名稱為item的數據,再進一步獲取其中名稱為age的數據與20進行比較,再得到具體的值。
R"({"item":{"age": 30}})"
動態綁定之后結果如下:
到此,可以認為這個XML是我們基礎布局模板,可以拿給Flex引擎計算了。
在組件布局的時候還時常需要對組件節點進行重復或者顯示與隱藏等操作,因此: 我們規定
for="{{for xx item xxs}}" 用于實現重復組件
if="{{ expr }}" 用于實現節點是否顯示
現在我們將XML的描述修改成下面這樣:
<View>
<View text="年齡: {{ 33.22 * 2}}" info="{{ item[name] }} : {{item[age]}}" color="{{ item[age] >= 20 ? '#FFFFFF' : '#DDDDDD' }}" for="{{ for item in items }}"/>
class="hljs-name"View>
XML原始節點展示如下:
首先我們需要遍歷節點的屬性,查找到節點中for字段的值是否為一個有效的循環表達式,然后對該循環表達式進行計算展開,結果如下:
R"({"item":{"age": 30},"items":[{"name": "小強", "age": 28},{"name": "小明", "age": 23},{"name": "小紅", "age": 18}]})"
**「這里需要特別注意的是:For會產生一個新的變量環境,for語句中定義了一個新的變量,當我們在展開時需要將新的變量(item)注入到變量環境中,item將覆蓋上一級環境變量中的item的值。
這與棧幀調用時的本地變量覆蓋上一級范圍中的變量是一樣的道理。
」** 展開之后,item是items中的每一個元素而不是根節點上的item了。
此時再對每個節點進行消解運算
注入的環境變量如下:
if語句相對簡單一點,它不會產生新的變量,只需要對表達式求值,獲取表達式的結果true則保留,false則刪除節點不展示。
測試一下,對一個相對復雜的模板進行動態綁定:
<View>
<View text="年齡: {{ 33.22 * 2}}" color="{{ item[age] >= 20 ? '#FFFFFF' : '#DDDDDD' }}" for="{{ for item in items }}">
class="hljs-name"View>
<View>
<View for="{{ for item in items }}">
展示結果如下,「這里需要注意的是當一個父節點在循環的時候,它的子節點也同樣會得到for生成的新變量,在展開子節點計算其屬性時,也能獲取到新的變量從而得到想要的結果。」
到這里,動態綁定就差不多了,接下來就是將綁定后的模板交給Flex引擎,計算而已了。
如果你覺得這個文章對你有用,可以分享給更多的朋友。
謝謝!
-
數據
+關注
關注
8文章
6888瀏覽量
88826 -
XML
+關注
關注
0文章
188瀏覽量
33041 -
渲染
+關注
關注
0文章
69瀏覽量
10908
發布評論請先 登錄
相關推薦
評論