在 semantic-ui 中有好看的评论样式,于是我们从中借鉴,进行简单的改造。
先看一下最终的实现效果
上面有评论的总条数,每条评论有:头像,作者,发表时间和内容。然后下面还有一个删 除的文本。最下面是发表回复的文本框,以及提交的按钮。
评论的数据,也将从 json 文件中获取。
[{"id":1,"author":"Dog Doggington","date":"2 days ago","content":"I think this is a great idea and i am voting on it","avatar":"./avatar.jpg"},{"id":2,"author":"Pawfin Dog","date":"2 days ago","content":"I think this is a great idea and i am voting on it","avatar":"./avatar2.jpg"},{"id":3,"author":"Dog Doggington","date":"2 days ago","content":"I think this is a great idea and i am voting on it","avatar":"./avatar.jpg"}]
可以看到一条评论是由:
id
当前评论的数据库 ID, 可以用来进行删除author
作者date
发表日期content
评论内容avatar
头像地址这些元素组成。
直接拿到 semantic-ui 的代码还不太符合我的要求,于是对它进行了必要的减化,最终 代码如下:
...
<!-- comments -->
<div class="ui piled blue segment" ms-controller="comments">
<h2 class="ui header">
<i class="icon inverted circular blue comment"></i> Comments {{comments.size()}}
</h2>
<div class="ui comments">
<div class="comment" ms-repeat="comments">
<a class="avatar">
<img ms-src="el.avatar">
</a>
<div class="content">
<a class="author">{{el.author}}</a>
<div class="metadata">
<span class="date">{{el.date}}</span>
</div>
<div class="text">
{{el.content|html}}
</div>
<div class="actions">
<a class="delete">Delete</a>
</div>
</div>
</div>
<form class="ui reply form">
<div class="field">
<textarea></textarea>
</div>
<div class="ui fluid blue labeled submit icon button">
<i class="icon edit"></i> Add Reply
</div>
</form>
</div>
</div>
<!-- end comments -->
...
这里只有几点要提示:
ms-controller="comments"
,在一个HTML页面中可以有多个 controllerms-repeat=comments
来进行数据循环,详细说明在下面{{comments.size()}}
,这里不使用 comments.length
是因为当数组长度 变化时,只有 size()
会引起页面重新进行渲染。el
是 ms-repeat
自动生成的循环变量ms-src
因为头像的图片地址是要使用变量,所以要将 src
属性改为 ms-src
这里只对 ms-repeat
作简单介绍,详细内容请参见下面的参考文档。
ms-repeat
类似于对一个数组进行循环,它放在将要重复生成的元素上,本例中就是 每条评论。这样,当前元素会根据数组的个数重复生成,包括其中的子元素。在循环时会 自动生成一些临时变量,用于DOM模板的处理,如:
el
这个表示循环变量,即当前正在处理的变量$first
如果是第一个元素,则为 true
$last
如果是最后一个元素,则为 true
$index
当前元素的索引值还有其它的一些临时变量,这里不详细描述。我们常用的就是 el
这个对象。
因此在下面,我们看到: el.avatar
, {{el.author}}
, {{el.date}}
, {{el.content|html}}
就不难理解了。它们都是通过当前元素来引用相应的具体的属性。
前面已经说过,因为使用了 el.avatar
这个变量,所以属性要使用 ms-src
。
下面是完整的 js 代码,包括 Blog 的基本信息展示:
...
<script>
var model = avalon.define("blog", function(vm){
vm.blog = {};
});
var comments = avalon.define("comments", function(vm){
vm.comments = [];
});
$(function(){
$.getJSON('blog_info.json').done(function(data){
model.blog = data;
});
$.getJSON('comments.json').done(function(data){
comments.comments = data;
});
});
</script>
...
看到了吗?就这么简单。比原来的内容,増加了:
$.getJSON()
获得评论数据的处理。这块就是一个简单的赋值,也没什么 多说的。对于评论总条数,我们没有特殊处理,只是使用了 {{comments.size()}}
,这样只要 评论条数变化,界面自动变化。真是省了大量的工作。
在 Avalon 中,是先有 ms-each
后来才出现的 ms-repeat
。它们两个使用不太一样:
ms-repeat
是定义在要循环的元素上,因此,不会影响其它同级和父元素。ms-each
是定义在父元素上,但是复制的是它下面的所有子元素。因此,如果你需要 在循环时,有些子元素不参与复制就没办法了。所以目前, ms-repeat
是更方便的用法。
ms-repeat
能不能定义 el
之外的循环变量?
答案:可以。使用 ms-repeat-name
。
ms-repeat
能不能支持多层嵌套?
答案:可以。示例参见: http://runjs.cn/code/8dss3sov