接上文:【大前端之前后分离01】JS前端渲染VS服务器端渲染,我们探讨了为什么要做前后分离,以及前端渲染需要解决的问题,最后提出了自己的解决方案:

前端代码编译形成两套代码:①前端发布版本 + ②服务器端脚本

这个想法借鉴了fis plus的smarty模块化思维,以及reactJS编译运行的概念,上次初步论证了其可行性,也遗留了一些问题,其中比较关键的问题是:

前端模块嵌套问题

我们在一个模板中又有一个widget,在子模板中又有一个widget,父模块与子模块中有数据依赖,或者子模块为一个循环,循环却依赖父模块某个值,这个便很麻烦。

举个例子来说,我们首页引入了一个商品模块,商品类型模块为一循环模块,里面又有子模块:

index首页模块:

1 <div id="type_widget_wrapper">
2   <script type="text/javascript">
3     render('text!./template/type.html', './model/type', './controller/type', 'type_widget_wrapper');
4   </script>
5 </div>

type模块:

 1 <ul id="type_id">
 2     <% for (var i = 0, len = data.length; i < len; i++) { %>
 3     <li class="type js_type">
 4         <h2><%=data[i].name%></h2>
 5         <ul class="product_list">
 6             <% for (var j = 0, len1 = data[i].product.length; j < len1; j++) { %>
 7                 <li class="product">
 8                     <%=data[i].product[j].name%>
 9                 </li>
10             <% } %>
11         </ul>
12     </li>
13     <% } %>
14 </ul>

可以看到,其中有第二次循环迭代的将该类型的商品信息读出,如果我们想将商品信息模块化的,这里便出现了模块嵌套情况:

 1 <ul id="type_id">
 2     <% for (var i = 0, len = data.length; i < len; i++) { %>
 3     <li class="type js_type">
 4         <h2><%=data[i].name%></h2>
 5         <ul class="product_list">
 6         <div id="product_list_widget_wrapper">
 7           <script type="text/javascript">
 8             render('text!./template/product_list.html', './model/product_list', './controller/product_list', 'product_list_widget_wrapper');
 9           </script>
10         </div>
11         </ul>
12     </li>
13     <% } %>
14 </ul>

这里暂时不考虑子模块中还有异步数据请求问题,我们将列表对应的模板放到了单个文件中:

1 <% for (var j = 0, len1 = data[i].product.length; j < len1; j++) { %>
2     <li class="product">
3         <%=data[i].product[j].name%>
4     </li>
5 <% } %>

这里的循环解析便是我们今天研究的重点,因为前端模块至少需要两个条件:

① 唯一的dom容器

② 能获取父级模块的相关数据

为了解决这个问题,我这里提出了迭代模块的概念。

迭代模块

所谓迭代模块,便是用于数据内嵌形式,并且处于循环中的模块,比如上述例子,我整个type模板就变成了这样(这里为最简形式):

 1 <ul id="type_id">
 2   <% for (var i = 0, len = data.length; i < len; i++) { %>
 3   <li class="type js_type">
 4     <h2>
 5       <%=data[i].name%></h2>
 6     <ul class="product_list">
 7 
 8       <div id="data_inner_widget_wrapper_<%=i %>">
 9         <script type="text/javascript">
10           iteratorRender({
11             index: typeof <%=i%> == 'string' ? '<%=i%>' : <%=i%>,
12             value: <%=JSON.stringify(data[i])%>,
13             name: 'data_inner'
14           });
15         </script>
16       </div>
17 
18     </ul>
19   </li>
20   <% } %>
21 </ul>

这个是编译过后形成的前端代码,最初是这样的:

 1 <ul id="type_id">
 2   <% for (var i = 0, len = data.length; i < len; i++) { %>
 3   <li class="type js_type">
 4     <h2>
 5       <%=data[i].name%></h2>
 6     <ul class="product_list">
 7         <%iteratorWidget({
 8           index: <%=i%>,
 9           value: <%=JSON.stringify(data[i])%>,
10           name: 'data_inner',
11         }); %>
12     </ul>
13   </li>
14   <% } %>
15 </ul>
1 <%iteratorWidget({
2   index: <%=i%>, //索引,整数或者字符串
3   value: <%=JSON.stringify(data[i])%>, //对应数据对象,字符串或者json对象
4   name: 'data_inner',
5 }); %>

这个时候前端需要实现iteratorRender方法,首先前端模板将上述代码解析结束后是这个样子的:

 1 "<ul id="type_id">
 2   
 3   <li class="type js_type">
 4     <h2>
 5       电脑</h2>
 6     <ul class="product_list">
 7 
 8       <div id="data_inner_widget_wrapper_0">
 9         <script type="text/javascript">
10           iteratorRender({
11             index: typeof 0 == 'string' ? '0' : 0,
12             value: {"id":1,"name":"电脑","product":[{"name":"戴尔"},{"name":"苹果"},{"name":"联想"},{"name":"华硕"}]},
13             name: 'data_inner'
14           });
15         </script>
16       </div>
17 
18     </ul>
19   </li>
20   
21   <li class="type js_type">
22     <h2>
23       书籍</h2>
24     <ul class="product_list">
25 
26       <div id="data_inner_widget_wrapper_1">
27         <script type="text/javascript">
28           iteratorRender({
29             index: typeof 1 == 'string' ? '1' : 1,
30             value: {"id":2,"name":"书籍","product":[{"name":"三国演义"},{"name":"西游记"},{"name":"红楼梦"},{"name":"水浒传"}]},
31             name: 'data_inner'
32           });
33         </script>
34       </div>
35 
36     </ul>
37   </li>
38   
39   <li class="type js_type">
40     <h2>
41       游戏</h2>
42     <ul class="product_list">
43 
44       <div id="data_inner_widget_wrapper_2">
45         <script type="text/javascript">
46           iteratorRender({
47             index: typeof 2 == 'string' ? '2' : 2,
48             value: {"id":3,"name":"游戏","product":[{"name":"仙剑1"},{"name":"仙剑2"},{"name":"仙剑3"},{"name":"仙剑4"}]},
49             name: 'data_inner'
50           });
51         </script>
52       </div>
53 
54     </ul>
55   </li>
56   
57 </ul>
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-07-23
  • 2021-10-17
  • 2021-09-05
  • 2022-12-23
  • 2021-09-15
猜你喜欢
  • 2021-12-05
  • 2021-12-15
  • 2022-12-23
  • 2021-12-27
  • 2021-05-07
  • 2021-11-04
相关资源
相似解决方案