慕课课程导航解析

338 查看

当[慕课网][1]经过一次改版之后,导航变得那是相当的高端,所以呢,我就想试着过一个类似的导航,就把慕课网的CSS样式拿过来了,做了一界面,但是具体功能是怎么实现的呢?
首先呢,分析一下,导航为两级,分类为一级,方向为二级,二级导航是一级导航的子类,一级导航是二级导航的父类,具体分为着几种情况:
1、点击(非“全部”)一级导航时,选中一级导航(增加背景色,即添加CSS样式 .on),根据所选分类的id,去获取对应所有方向(用到下面的第一个方法),并展示在二级导航中,如果点击一级导航中的“全部”,就获取所有方向(用到下面的第二个方法),并展示在二级导航中。
2、点击(非“全部”)二级导航时,选中二级导航,选中对应一级导航,此时二级导航中的 “全部”和一级导航的指向一致(即链接一致),如果点击二级导航中的 “全部”,获取一级导航中被选中分类的所有方向。
采用SSSP(SpringMVC,Spring,SpringData,JPA)分层设计,使用MySQL数据库。

第一步实体:

/**
*树状映射
*/
@Table(name="imooc_category")
@Entity
public class Category{
    @Id  @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;
    private String name;
    private Category parent;//父类别
    private Set<Category> children = new HashSet<Category>();//子类别
        @Id @GeneratedValue(strategy=GenerationType.AUTO)
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    @Column(length=20, nullable=false)
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
        @ManyToOne(cascade={CascadeType.REFRESH}, optional=true, fetch=FetchType.LAZY) 
    @JoinColumn(name="CATEGORY_ID")
    public Category getParent() {
        return parent;
    }
    public void setParent(Category parent) {
        this.parent = parent;
    }
    @OneToMany(mappedBy="parent", cascade={CascadeType.REFRESH, CascadeType.REMOVE})
    public Set<Category> getChildren() {
        return children;
    }
    public void setChildren(Set<Category> children) {
        this.children = children;
    }
}

第二步持久层:

public interface CategoryRepository extend JpaRepository<Book, Integer>{
    //根据父类别id获取所有对应子类别
     public List<Category> findByParent_Id(Integer id);
    //获取所有子类别
    public List<Category> findByParentIsNotNull();
     //获取类别
        public Category findById(Integer id);
 }

第三步业务层:

@Service("categoryService")
 public class CategoryService{
        @Autowire private CategoryRepository categoryRepository;//依赖注入

         //根据父类别id获取所有子类别
        @Transaction(readOnly=true)
       public List<Category> findByParent_Id(Integer id){
            return categoryRepository.findByParent_Id(id);
        }
         /获取所有子类别
        @Transaction(readOnly=true)
        public List<Category> findByParentIsNull(){
                  return categoryRepository.findByParentIsNotNull();
        }
      //获取类别
        @Transaction(readOnly=true)
        public Category findById(Integer id) {
               return categoryRepository.findById(id);   
        }
}

第四步控制层:

@Controller
public class CategoryHandler{
      @RequestMapping("/book/list/category/{id}")
      public String searchCouseList(@PathVariable("id") Integer id, Map<String, Object> map){
       if(id > 0){
      Category category = categoryService.getById(id);//按id 获取对应类别
      Category parent = category.getParent();//获取其父类别
       if(parent == null){//说明点击的是一级导航,如果为空说明点击的是分类(即顶级类别), 那就获取当前类别的所欲子类别
             map.put("categories", categoryService.getByParentId(id));
       } else {//说明点击的是方向(即二级类别),,那就获取当前类别父类的所有子类别, 也就是其兄弟类别
                 map.put("categories", categoryService.getByParentId(parent.getId()));
            map.put("cateParentid", parent.getId());
       }
        map.put("cateid", id);//选中类别id
     } else {
          map.put("categories", categoryService.findByParentIsNotNull());//获取所有富类别
     }
       return "front/search";
   }
 }

视图层:search.jsp核心代码

<div class="book-nav-row cf">
            <span class="hd l">方向:</span>
        <div class="bd">
            <ul>
                <li class="book-nav-item <c:if test="${empty cateid}">on</c:if>"><a href="<%=beaspPath%>/book/list/category/0">全部</a></li>
                <li class="book-nav-item <c:if test="${cateParentid eq 1 }">on</c:if> <c:if test="${cateid eq 1 }">on</c:if>"><a href="<%=beaspPath%>/book/list/category/1">文艺</a></li>
                <li class="book-nav-item <c:if test="${cateParentid eq 6 }">on</c:if> <c:if test="${cateid eq 6 }">on</c:if>"><a href="<%=beaspPath%>/book/list/category/6">青春</a></li>
                <li class="book-nav-item <c:if test="${cateParentid eq 8 }">on</c:if> <c:if test="${cateid eq 8 }">on</c:if>"><a href="<%=beaspPath%>/book/list/category/8">教育</a></li>
                <li class="book-nav-item <c:if test="${cateParentid eq 11 }">on</c:if> <c:if test="${cateid eq 11 }">on</c:if>"><a href="<%=beaspPath%>/book/list/category/11">生活</a></li>
                <li class="book-nav-item <c:if test="${cateParentid eq 15 }">on</c:if> <c:if test="${cateid eq 15 }">on</c:if>"><a href="<%=beaspPath%>/book/list/category/15">人文社科</a></li>
                <li class="book-nav-item <c:if test="${cateParentid eq 22 }">on</c:if> <c:if test="${cateid eq 22 }">on</c:if>"><a href="<%=beaspPath%>/book/list/category/22">经管</a></li>
                <li class="book-nav-item <c:if test="${cateParentid eq 26 }">on</c:if> <c:if test="${cateid eq 26 }">on</c:if>"><a href="<%=beaspPath%>/book/list/category/26">科技</a></li>
                <li class="book-nav-item <c:if test="${cateParentid eq 33 }">on</c:if> <c:if test="${cateid eq 33 }">on</c:if>"><a href="<%=beaspPath%>/book/list/category/33">励志</a></li>
                </ul>
            </div>
        </div>
        <div class="book-nav-row cf">
            <span class="hd l">分类:</span>
                <div class="bd">
                    <ul>
                        <li class="book-nav-item <c:if test="${empty cateParentid}">on</c:if>"><a href="<%=beaspPath%>/book/list/category/<c:if test='${empty cateParentid }'>${cateid}</c:if><c:if test='${!empty cateParentid }'>${cateParentid}</c:if>">全部</a></li>
                        <c:forEach items="${categories }" var="c">
                            <li class="book-nav-item <c:if test="${c.id==cateid }">on</c:if>"><a href="<%=beaspPath%>/book/list/category/${c.id}">${c.name }</a></li>
                        </c:forEach>
                    </ul>
                </div>
            </div>
</div>
至此结束,至于如何SSSP一些知识,还是看慕课网相关视频,还有文档。
SpringData文档:[官方文档][2]