构建更好的客户端 JavaScript 应用 【已翻译100%】

简介:

你可能注意到了,最近的一段时间越来越多的Web应用有变复杂的趋势,重心从服务端慢慢向着客户端转移。 这是个正常的趋势么?我不知道。支持和反对者的讨论就像是在讨论复活者和圣诞节哪一个更好一样; 很难说哪一方观点就是完全正确的。因此,本文不会探讨究竟哪一方是对的,不过我还是试图解释一下使用大家所熟知的面向对象编程也许可以成功的解决客户端编程中存在的一些问题。

不太规范的代码的示例
为了顾及一个应用的响应以及用户体验, 导致我们创建了持续增长的复杂的代码, 这些代码变得难于理解和维护。 你可以轻松的想到在没有任何构架和遵循规则构建出客户端的JavaScript应用代码将会这样:

$(function(){
    $('#form').submit(function(e) {
        e.preventDefault();

        $.ajax({
            url: '/animals',
            type: 'POST',
            dataType: 'json',
            data: { text: $('#new-animal').find('textarea').val() },
            success: function(data) {
                $('#animals').append('<li>' + data.text + '</li>');
                $('#new-animal').find('textarea').val('');
            }
         });
     });
});

维护这一类的代码将会很难。因为这短短的一段代码与很多地方都有关联: 它控制着很多的事件 (站点, 用户, 网络事件), 它要处理用户的操作事件, 要解析服务器返回的应答并且产生HTML代码。 有人可能说: “是的,你说的对, 但是如果这不是一个客户端单页的页面应用?这最多算是一次过度使用jQuery类库的例子” ——不是很有说服力的观点, 因为众所周知,易于维护和精心设计的代码是非常重要的。特别是许多的工具或者是框架致力于保持代码可用以便于我们能更简单的去测试、维护、重用、和扩展它。

MV*是什么?

谈到这里。我们能受益于那些基于MVC的JavaScript框架,但这些框架大部分不使用MVC,并且相当于Model和Videw的一种结合,或者在二都之间的一些东西,这很难去分清。这就是为什么说大部分的Javascript框架是基于MV*。

改变方法或许可以提供项目中客户端的组织和架构,这使得代码可以在很长的一段时间内容易维护,即使重构已经有的代码也变得相对容易。知道他如何工作和下面一些问题的答案是必需要要记住的。

  • 我的应用里有哪些类型的数据?-Model
  • 用户应该看到什么?-View
  • 谁是和用户交互的程序?-Controller

使用MVC框架重构代码
受用MVC重构代码有什么好处?

  • 解除DOM和Ajax的依赖
  • 代码有更好的结构,并且更容易测试。
  • 从 $(document).ready()中删除多余的代码,只留下使用Model创建Links的部分。

让我们使用一些简单步骤来重构一个典型的代码块

步骤 1: 创建视图并移动Ajax请求

我们开始解除DOM和Ajax的依赖. 使用prototypes建造者,模式创建'Animals' 对象,并且添加一个 'add' 方法.同时创建视图 'NewAnimalView' , 并且添加方法'addAnimal'、 'appendAnimal' 、'clearInput'.

代码如下:

var Animals = function() {
};

Animals.prototype.add = function (options) {
     $.ajax({
         url: '/animals',
         type: 'POST',
         dataType: 'json',
         data: { text: options.text },
         success: options.success
     });
};

 var NewAnimalView = function (options) {
    this.animals = options.animals;
    var add = $.proxy(this.addAnimal, this);
    $('# form').submit(add);
 };

 NewAnimalView.prototype.addAnimal = function(e) {
     e.preventDefault();
     var self = this;

     this.animals.add({
         text: $('#new-animal textarea').val(),
         success: function(data) {
             self.appendAnimal (data.text);
             self.clearInput();          
         }
     });
 };

NewAnimalView.prototype.appendAnimal = function(text) {
    $('#animals ul').append('<li>' + data.text + '</li>');
};
NewAnimalView.prototype.clearInput = function() {
    $('#new-animal textarea').val('');
};

 $(document).ready(function() {
     var animals = new Animals();
     new NewAnimalView({ animals: animals });
 });

步骤 2: 使用事件解除依赖.
这个例子,利用MVC框架是关键。我们将会用到事件机制, 事件使我们结合和触发自定义事件. 因此,我们创建新的“AnimalsView”和“NewAnimalView”,并且赋予它们不同的显示animals的职责。 使用事件就来区别职责非常简单。如果在方法和事件之间传递职责,如下所示:

var events = _.clone(Backbone.Events);
var Animals = function() {
};

Animals.prototype.add = function(text) {
     $.ajax({
         url: '/animals',
         type: 'POST',
         dataType: 'json',
         data: { text: text },
         success: function(data) {
            events.trigger('animal:add', data.text);
         }
     });
};

var NewAnimalView = function(options) {
    this.animals = options.animals;
    events.on('animal:add', this.clearAnimal, this);
    var add = $.proxy(this.addAnimal, this);
    $('# form').submit(add);
 };

NewAnimalView.prototype.addAnimal = function(e) {
     e.preventDefault();
     this.animals.add($('#new-animal textarea').val());
 };

NewAnimalView.prototype.clearInput = function() {
    $('#new-animal textarea').val('');
};

var AnimalsView = function() {
    events.on('animal:add', this.appendAnimal, this);
};

AnimalsView.prototype.appendAnimal = function(text) {
    $('#animals ul').append('<li>' + data.text + '</li>');
};

$(document).ready(function() {
     var animals = new Animals();
     new NewAnimalView({ animals: animals });
     new AnimalsView();
});

步骤 3: 传递数据结构到核心框架
最后,最重要的一步,我们使用: models, views and collections.

var Animal = Backbone.Model.extend({
    url: '/animals'
});

var Animals = Backbone.Collection.extend({
    model: Animal
});

var AnimalsView = Backbone.View.extend({
    initialize: function() {
        this.collection.on('add', this.appendAnimal, this);
    },

    appendAnimal: function(animal) {
        this.$('ul').append('<li>' + animal.escape('text') + '</li>');
    }
});


var NewAnimalView = Backbone.View.extend({
    events: {
        'submit form': 'addAnimal'
    },

    initialize: function() {
        this.collection.on('add', this.clearInput, this);
    },

    addAnimal: function(e) {
        e.preventDefault();
        this.collection.create({ text: this.$('textarea').val() });
    },

    clearInput: function() {
        this.$('textarea').val('');
    }
});

$(document).ready(function() {
    var animals = new Animals();
    new NewAnimalView({ el: $('#new-animal'), collection: animals });
    new AnimalsView({ el: $('#animals'), collection: animals });
});

总结

我们已经实现什么呢?我们在高度的抽象上工作。代码的维护、重构和扩展变得更容易。我们极大的优化了代码结果,是不是很迷人?太棒了。但是,我可能要给你泼冷水,即使最好的框架,开发的代码仍旧是脆弱并且难以维护。因此,如果你认为使用了一个较好的MV*框架能解决所有代码上的问题是错误的。记住在重构过程中,经历了第二步,代码会变得好很多,我们不使用框架的主要组件。

记住MV*框架是好的这一点,但是所有关注在‘How’去开发一个应用,这让程序开发人员头决定‘What’。每个框架的一个补充,尤其是当项目的Domain很复杂,将是Domain驱动设计方法,这将更关注与下面的方面:“what”, 把需求转化为真正的产品的一个过程。但是,这是我们要讨论的另外一个主题。

相关文章
|
13天前
|
前端开发 JavaScript
使用JavaScript实现复杂功能:构建一个自定义的拖拽功能
使用JavaScript实现复杂功能:构建一个自定义的拖拽功能
|
1月前
|
JavaScript 前端开发 开发工具
使用Vue.js、Vuetify和Netlify构建现代化的响应式网站
使用Vue.js、Vuetify和Netlify构建现代化的响应式网站
38 0
|
1月前
|
开发框架 前端开发 JavaScript
使用JavaScript、jQuery和Bootstrap构建待办事项应用
使用JavaScript、jQuery和Bootstrap构建待办事项应用
13 0
|
1月前
|
自然语言处理 JavaScript 前端开发
探索JavaScript中的闭包:理解其原理与实际应用
探索JavaScript中的闭包:理解其原理与实际应用
19 0
|
1月前
|
JavaScript 前端开发 算法
js开发:请解释什么是虚拟DOM(virtual DOM),以及它在React中的应用。
虚拟DOM是React等前端框架的关键技术,它以轻量级JavaScript对象树形式抽象表示实际DOM。当状态改变,React不直接操作DOM,而是先构建新虚拟DOM树。通过高效diff算法比较新旧树,找到最小变更集,仅更新必要部分,提高DOM操作效率,降低性能损耗。虚拟DOM的抽象特性还支持跨平台应用,如React Native。总之,虚拟DOM优化了状态变化时的DOM更新,提升性能和用户体验。
23 0
|
9天前
|
开发框架 前端开发 JavaScript
采用C#.Net +JavaScript 开发的云LIS系统源码 二级医院应用案例有演示
技术架构:Asp.NET CORE 3.1 MVC + SQLserver + Redis等 开发语言:C# 6.0、JavaScript 前端框架:JQuery、EasyUI、Bootstrap 后端框架:MVC、SQLSugar等 数 据 库:SQLserver 2012
|
13天前
|
JavaScript 前端开发 API
Vue.js:构建高效且灵活的Web应用的利器
Vue.js:构建高效且灵活的Web应用的利器
|
28天前
|
开发框架 JavaScript 前端开发
描述JavaScript事件循环机制,并举例说明在游戏循环更新中的应用。
JavaScript的事件循环机制是单线程处理异步操作的关键,由调用栈、事件队列和Web APIs构成。调用栈执行函数,遇到异步操作时交给Web APIs,完成后回调函数进入事件队列。当调用栈空时,事件循环取队列中的任务执行。在游戏开发中,事件循环驱动游戏循环更新,包括输入处理、逻辑更新和渲染。示例代码展示了如何模拟游戏循环,实际开发中常用框架提供更高级别的抽象。
11 1
|
1月前
|
Web App开发 JavaScript 前端开发
使用Node.js和Express构建RESTful API
使用Node.js和Express构建RESTful API
18 0
|
1月前
|
JavaScript 前端开发 API
Vue.js:构建现代化Web应用的灵活选择
Vue.js:构建现代化Web应用的灵活选择
40 0