• 前端编程提高之旅(六)----backbone实现todoMVC


                乐帝当年学习backbone时。最開始是看官网todoMVC的实现。后来了解到requireJS便于管理JS代码。就对官网代码做了requireJS管理。但此时乐帝感觉此时的todoMVC仍然不够简明,为了加深对MVC架构的理解。乐帝对原有appview代码进行了重构,将相关显示模块单独提取出自称view。实现view原子化。乐帝已经将这个项目上传(下载地址)。

        增加requireJS的文件夹结构:

       这里主要用到templates用于放置view相应的模板。views则相应backbone中view文件。假设说backbone是前端MVC,那么model是对数据建立模型。collection则是对model统一管理,view则起到控制器的作用,用于填充数据到模板,并渲染模板到显示。model、collection起到M作用。view起到C的作用,模板则起到V的作用。

       然后我们看一下todoMVC的效果图:



        从终于效果图。我们能够分析出,要对原有appview中解耦出原子view。就须要推断出哪些是原子view。原子view须要具备两点:

    • 具有动态交互效果
    • 与其它页面部分独立
       当然这里的原子view定义还值得商榷。乐帝依据以上两个原则对view进行了又一次划分。
       且看views文件夹结构:

       相应模板文件夹结构:
       须要注意的是,这里appview并没有相应的模板。而是通过设置el: "#todoapp",在index.html文件里,统一对原子view进行管理。

       以下以ToggleAllView类源码为样例,我们分析下,原子view职能的组成:
    define([
        'jquery',
        'underscore',
        'backbone',
        'text!templates/toggleAll.html'
    ], function($, _, Backbone, toggleTemplate) {
        var ToggleAllView = Backbone.View.extend({
            toggleTemplate: _.template(toggleTemplate),
            events: {
                "click #toggle-all": "toggleAllComplete"
            },
            initialize: function() {
                this.listenTo(this.collection, "all", this.render); //除了todoview与todomodel一一相应
                // 其它相关操作都会监听collection
            },
            render: function() {
                this.$el.html(this.toggleTemplate());
                var done = this.collection.done().length;
                var remaining = this.collection.remaining().length;
                this.allCheckbox = this.$("#toggle-all")[0];
                this.allCheckbox.checked = !remaining;
                return this;
            },
            toggleAllComplete: function() {
                var done = this.allCheckbox.checked;
                this.collection.each(function(todo) {
                    todo.save({
                        done: done
                    });
                }); //这里通过推断单选框是否选中。改动全部modeldone属性
            }
    
        });
        return ToggleAllView;
    });

       上述代码中职能主要有例如以下几种:
    • 设置el或tagname,用于定义在上一层view放置的位置,或包裹的标签
    • 设置相应模板(Template)
    • 定义交互事件,并连带定义交互函数
    • 初始化函数(initialize),一般设置对collection或者model的监听,用于view之间的通信
    • 渲染函数(render),用于渲染数据到模板中。设置其它一些全局函数
       由此可见。原子view将职能划分的非常清楚。这也是前端MVC架构的原因,而不是之前纯脚本时代,代码间高度耦合。牵一发而动全身。
       对于学习backbone,原子view和appview各自代码都不难理解。难于理解或者它精妙之处,在于对事件的监听机制,正是这样的机制,处理了view之间的通信,从而将松散的view拼装成性能优良的整理。

       todoView的监听:
    initialize: function() {
                this.listenTo(this.model, "change", this.render);
                this.listenTo(this.model, "destroy", this.remove); //当模型被删除,视图对应被移除
    
            }

       这里对每一个todoview进行与之绑定的model数据监听。改动,则又一次渲染;销毁。则移除此todoview。

       再看ToggleAllView的监听:
    initialize: function() {
                this.listenTo(this.collection, "all", this.render); //除了todoview与todomodel一一相应
                // 其它相关操作都会监听collection
            }

       这个监听更“狠”。仅仅要collection有变动,就会又一次渲染,以达到实时交互的效果。

       那么appview是怎样管理各个子view的呢?
       且看两个appview函数:
     initialize: function() {
          // 初始化加入各种视图,新建视图并加入到父视图指定位置
          this.footer = this.$el.find('footer');
          this.main = $('#main');
          this.todoCollection = new todos;
          inputview = new InputView({
            collection: this.todoCollection
          });
          $("#todoapp").prepend(inputview.render().el); //加入输入框
    
          var toggleAllview = new ToggleAllView({
            collection: this.todoCollection
          });
          this.main.prepend(toggleAllview.render().el); //取得数据后,再初始化
          this.allCheckbox = this.$("#toggle-all")[0];
    
          this.listenTo(this.todoCollection, "add", this.addOne);
          this.listenTo(this.todoCollection, "reset", this.addAll);
          this.listenTo(this.todoCollection, "all", this.render);
          // 须要数据的视图。在获取数据后定义
          this.todoCollection.fetch();
          // 状态视图
          statusview = new StatusView({
            collection: this.todoCollection
          });
          this.footer.append(statusview.render().el); //取得数据后,再初始化
        },
        render: function() {
          // 因为设置了all监听全部collection的操作。故加入一个项就会被渲染一次,这保证了有修改都会得到渲染到页面
          var done = this.todoCollection.done().length;
          var remaining = this.todoCollection.remaining().length;
          this.allCheckbox = this.$("#toggle-all")[0];
          if (this.todoCollection.length) {
            //渲染时运行显示或隐藏的代码
             this.main.show();
             this.footer.show();
            this.footer.html();
            //假设collection为空的话,则清空footer
          } else {
            this.main.hide();
            this.footer.hide();
          }
        }, // 实现总体显示


       与原子view的差别,在于appview初始化函数除了监听collection变化外。还初始化各个原子view,并加入到指定界面位置,同一时候渲染函数依据逻辑须要。渲染整个页面。
       以上是对整个todoMVC程序的总体性架构分析。详细交互细节可查看乐帝源码。

  • 相关阅读:
    关于javascript with性能的一段阐述
    关于多线程传参问题
    C++ 入门简要笔记
    html中多个title
    关于大学生对抖音的使用情况调查分析报告
    eclipse如何导入lib文件夹下的包
    每周总结
    中文分词——jieba之分词后存入数据库
    软件需求与分析课堂测试十 — 软件设计师案例分析(历年软考题选取)
    2021年秋季学期课程总结及奖励加分
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/5161432.html
Copyright © 2020-2023  润新知