作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
骨干.js 是一个极简框架,旨在提供一组简单的数据结构和功能,你可以用它来创建一个结构化的web应用程序的前端. 开箱即用,骨干组件.Js提供了一个直观的环境,当您在后端处理模型和视图时,您可能已经很熟悉了. 骨干中的模型和集合.j很简单, 但是它们有一些非常有用的功能, 比如可以轻松地将它们与REST JSON api集成. 但它们也足够灵活,可以适应几乎任何实际用途.
在这个主干.在Js教程中,我们将看看一些常见的错误 自由开发人员 他们第一次尝试学习骨干.j和避免它们的方法.
骨干.js可能是一个极简框架,但它(以及下划线.Js)提供了大量的特性和功能,可以很容易地满足开发现代web应用程序时出现的最基本和一些关键需求. 初级开发人员经常犯的一个常见错误是他们使用骨干.js是另一个类似mvc的web客户端框架. 尽管本节讨论的是一些非常明显的东西,当涉及到骨干时.因此,不彻底探索框架是一个非常严重的错误. 框架可能很小, 但这正是它成为这次彻底探索的绝佳候选者的原因. 尤其是它的小 精心注释的源代码.
骨干.Js提供了给你的web应用程序可以从中受益的结构所需的最少的东西. 具有可扩展性和 过多的插件、学习骨干.Js可以用来构建一些令人惊叹的web应用程序. 骨干的一些最明显的特性.j是通过模型、集合和视图公开的. 路由器和历史组件提供了一种简单而优雅的机制来支持客户端路由. 虽然 下划线.js 是骨干的依赖.js, 它很好地集成到框架中, 因为模型和集合都受益于这个惊人的JavaScript实用工具带,也可以在您的处置.
框架的源代码写得很好,注释也很好,喝杯咖啡就能看完. 初学者可以从阅读源代码注释中获益良多, 因为他们可以学到很多关于框架内部如何工作的知识, 也 采用一套简洁的最佳实践 当涉及到JavaScript时.
这是我们刚开始学习骨干的时候会做的事情.js就是不做骨干推荐的事情.js. 例如, 我们倾向于在简单的网站上使用jQuery来处理事件和查看更新. 骨干.Js旨在通过适当的关注点分离为您的web应用程序提供严格的结构. 我们经常用骨干做什么.是更新一个视图,以响应任意DOM事件:
var AudioPlayerControls =主干.视图.扩展({
事件:{
“点击 .btn-play, .Btn-pause ':函数(事件){
美元(事件.目标).toggleClass(“btn-play btn-pause”)
}
},
// ...
})
这是应该不惜一切代价避免的事情. It may be possible to come up with obscure examples where 这 may make sense; but in most cases, 有很多更好的方法. 事实上, 我可以在这里举例说明的一种方法是使用模型来跟踪音频播放器的状态,并使用该状态信息来渲染按钮(或者更具体地说,它的类名):
var AudioPlayerControls =主干.视图.扩展({
事件:{
“点击 .btn-play, .Btn-pause ':函数(事件){
这.模型.集(“玩”, !这.模型.('玩'))
}
},
初始化:函数(){
这.听(这.模型,“改变”,这个.渲染)
这.呈现()
},
// ...
})
在很少的情况下,从事件处理程序直接操作DOM是有意义的, 但是管理来自事件处理程序的复杂DOM操作所涉及的成本几乎是不值得的. 这是脊梁.Js旨在解决. 使用主干.做这样的事情是错误的.
由于骨干.js使得随意渲染和重新渲染DOM或响应事件变得非常容易, 我们经常忽略这对web应用程序的整体性能有多大的影响. 有很多方法可以让我们在视图上改变渲染方法. 通常情况下,这似乎并不多, 随着现代网络浏览器成为高性能的软件. 但是随着web应用程序的发展, 它处理的数据量也在增长, 性能的下降变得越来越明显.
我们可以通过一个人为的例子来看到这一点,我们从一个小的模型集合开始, 然后渲染到列表视图中:
var AudioPlayerPlaylist = 骨干.视图.扩展({
模板:_.template(‘ <% _.each(musics, function(m) { %> - <%- m.title %>
<% }) %>
’),
初始化:函数(){
这.听(这.Collection, ' add ', 这.渲染)
},
// ...
})
在这个主干.在Js的例子中,每当一个模型被添加到集合中时,我们都会重新渲染. 这样就可以了. 然而, 因为每次将模型添加到列表中时都会触发“add”事件, 想象一下从服务器获取一个大的模型列表. 呈现方法将被连续调用多次, 对来自服务器的响应中的每个模型执行一次. 一个足够大的模型将足以使您的应用程序出现问题并破坏用户体验. 有时一个小的响应就足够了,这取决于所呈现视图的复杂性.
一个非常快速的解决方案是简单地不为每个正在添加的模型调用渲染方法. 在这种情况下, 将批量添加模型, 你可以做一些事情让渲染功能只在它被调用时触发而不是在指定的时间内被重新调用. 骨干.js的依赖下划线.Js提供了一个方便的实用函数:“_.防反跳”. 你所需要利用的就是用下面的代码改变事件绑定的JavaScript行:
这.听(这.收集,'添加',_.防反跳(_.绑定(这.渲染),128))
这将导致每次“add”事件发生时触发事件回调, 然而, 在实际调用呈现方法之前,它将从最后一个事件等待128毫秒.
在大多数情况下,这将被视为一种快速修复的解决方案. 事实上,有更合适的方法来避免渲染抖动. Trello背后的开发人员 写了一篇博文 讨论他们在使用骨干时提高渲染性能的经验和方法.js.
不管使用什么JavaScript框架,都可能会绑定未使用的事件侦听器, 或者你根本不用. 即使是骨干.Js可以很容易地避免这个问题, 在您的web应用程序中仍然留下可能导致内存泄漏的潜在漏洞当然是错误的. 骨干的“Event”组件.Js当然是一个非常简洁的实现. 它允许JavaScript对象轻松实现基于事件的特性. 因为视图是大多数事件消费通常发生的地方, 在这里很容易犯这样的错误:
var AudioPlayerControl = 骨干.视图.扩展({
初始化:函数(){
这.模型.(“改变”,_.绑定(这.渲染,))
// ...
},
// ...
})
这段代码中的事件绑定行与第一个示例中的事件绑定行没有太大区别. 我们所做的只是改变了“这”.听(这.模型,…)“到”这个.模型.on(…)”. 既然我们都很习惯.on()“从我们使用其他JavaScript框架和库的经验来看,调用事件绑定, 当我们开始使用骨干时.我们通常会用".On() "调用绑定事件. 如果我们不厌其烦地打个电话,那就好了。”.Off() "用于在不再需要事件处理程序时解除绑定. 但我们很少这样做,这最终成为内存泄漏的一个来源.
骨干.Js提供了一种简单的方法来解决这个问题. 这是通过使用“对象”实现的.听()方法. 这使您正在调用“listenTo()”的对象能够跟踪它正在侦听的事件, 同时也可以很容易地一次解除所有事件的绑定. 的观点, 例如, 自动停止监听所有绑定事件,只要你调用它的“remove()”.
如果你仔细想想,骨干.Js的极简主义为你如何构建web应用程序的前端提供了极大的灵活性. 与模型, 集合, 视图是组件的构建块, 重要的是,您要保持它们的轻量级和尽可能具体. 通常, 就代码而言,视图最终会成为web应用程序中最繁重的部分. 但是非常重要的一点是,不要最终创建巨大的整体视图,从而试图完成应用程序必须提供的所有功能. 而不是制作一个巨大的“AudioPlayer”视图,里面塞满了所有的逻辑, 将其拆分为许多逻辑视图,例如播放列表视图, 控件的视图, 可视化工具的视图, 等等......。. 您想要确保的粒度类型可能取决于您要构建的应用程序.
这是因为使用粒度视图, 每个视图都做一些特定的事情,并且做得对吗, 用骨干开发一个web应用程序.Js变得轻而易举. 您的代码应该更易于维护,并且在将来易于扩展或修改. 然后还有另一个极端,你最终会做得过火. 骨干.Js视图的设计是为了方便您使用模型或集合, 这可能会提示你应该如何构建你的应用程序. 伊恩·斯托姆·泰勒 分享一些有价值的想法 在他的博客中,你在实现视图时应该记住这一点.
骨干.js可以使用开箱即用的基于json的RESTful api. 您所需要的就是jQuery(或者它的替代品,比如Zepto)。. 然而,骨干.Js具有极强的可扩展性. 事实上,主干.js可以适应使用其他类型的api和其他类型的编码格式.
主干的组成.处理前端与后端服务交互的是“Sync”。. 该组件公开了许多属性,您可以轻松地覆盖这些属性来定制骨干.js与API端点交互的方式. 事实上, 也可以用一些不那么传统的机制来代替默认的同步机制, 例如使用localStorage来持久化数据, 而不是后端服务.
众多 插件 使自定义主干很容易.Js的同步行为. 例如,一个名为 骨干.dualStorage 允许您同时使用后端服务和localStorage来持久化数据. 当应用程序脱机时, 该插件使用localStorage从缓存数据中保存服务请求, 并跟踪稍后联机时可能与服务器同步的更改.
虽然使用主干.js的后端被设计为RESTful并与之兼容,这样更容易使用, 这并不意味着这都是骨气.Js可以与. 通过对默认主干进行一些更改.js的同步机制,你可以使它适应广泛的后端服务api和编码格式.
值得一提的是,骨干的其他部分.j也是灵活的,并且在某些方面是可选的. 例如,您不必使用下划线附带的默认模板引擎.js. 您甚至不必使用骨干的视图组件.Js,如果你想的话,可以用其他东西来替换它.
我们可能经常犯的一个错误,作为一个初学者学习骨干.Js将数据作为属性直接存储在视图中. 这些数据可能用于跟踪某些状态或某些用户选择. 这是应该避免的.
var AudioPlayerVisualizer =主干.视图.扩展({
事件:{
“点击 .Btn-color ': function(event) {
这.colorHex = 美元(事件.目标).数据(“color-hex”)
这.呈现()
}
},
// ...
})
您总是可以创建一些没有端点的附加模型和集合. 这可以帮助您存储不一定必须在后端持久化的数据, 或者本质上是暂时的. 将它们存储在模型中可以使您能够侦听更改. 相关观点, 甚至是多个视图, 可以观察这些模型并在必要时重新渲染它们自己吗.
想象一下,如果您实际将状态跟踪变量存储在视图中,并且每次更改它们时都必须调用渲染方法. 只要缺少对这个渲染方法的一次调用,就可能使应用程序处于中断状态, 就用户在屏幕上的体验而言. 此外, 对于小视图,你可能需要在多个视图对象上同步这些状态变量,然后还必须对它们调用渲染方法.
骨干.在我看来,js有一种处理DOM事件的绝妙方法. 不使用它会带来很多缺点. jQuery的“.On()”事件绑定函数看起来很方便,但从长远来看往往会带来麻烦. 例如, 当元素从DOM中分离出来时, jQuery会自动删除所有绑定到元素的事件处理程序。.on()”. 这意味着,如果您从DOM中分离根元素并重新附加它,那么您试图从视图中绑定到的任何DOM事件都需要被反弹.
var AudioPlayerControls =主干.视图.扩展({
事件:{
“点击 .btn-play, .Btn-pause ':函数(){/* ... */ },
“点击 .Btn-prev ':函数(){/* ... */ },
“点击 .Btn-next ':函数(){/* ... */ },
“点击 .Btn-shuffle ':函数(){/* ... */ },
“点击 .Btn-repeat ': function() {/* ... */ }
},
// ...
})
当与此视图对应的元素被重新附加到DOM时, 你所要做的就是在视图上调用“delegateEvents()”来绑定所有这些事件.
注意,理解这些事件是如何绑定的非常重要. 而不是将事件绑定到由选择器指定的元素上.Js实际上将事件处理程序绑定到视图的根元素. 这在几乎所有情况下都很有效,实际上对我们的大多数需求都更有效. 更改或替换视图DOM子树中的子元素不需要骨干.Js将每个事件再次绑定到新元素上. 现有的侦听器只是继续工作.
然而,这将阻止某些事件被监听. 举个例子,你可能 想要监听“window”上的滚动事件 或者在子可滚动元素上. 对于子元素,您可以为该元素创建一个子视图,并在那里处理事件.
骨干.js, 是一个非常紧凑但可扩展的框架, 对于需要大量后台灵活性的web应用程序来说,这是一个很好的选择吗. 不像Angular这样的框架.js和Ember.js总是在那里告诉你如何做你想做的事情,骨干.Js退后一步,提供了一组强大的工具,并让您决定如何使用它们. 我希望这个骨干.Js初学者教程将帮助您避免一些常见的问题 发展的错误 然后用它创造一些惊人的东西.
Mahmud是一名软件开发人员,拥有多年的经验和效率诀窍, 可伸缩性, 稳定的解.
13
世界级的文章,每周发一次.
世界级的文章,每周发一次.