gpt4 book ai didi

javascript - Rails 前端的最佳实践是什么?

转载 作者:行者123 更新时间:2023-11-29 21:31:03 24 4
gpt4 key购买 nike

我是一名前端开发人员,目前在一个大型 Rub​​y on Rails 项目的团队中工作。这不是SPA。所有页面呈现都在服务器端完成。

项目有几十个 View ,逻辑如下

if true render this partial else render another partial

我尝试遵循 DRY 原则,我从 arkency blog 中学到了很多东西,并尝试实现尽可能多的可重用组件。

但我觉得缺少 React 中的 componentDidMount 之类的东西。

所以我的问题是:在 rails partials 中编写内联 javascript(即添加逻辑)是否可以?为可维护的 Rails 应用程序编写 Javascript 的最佳方式是什么?

最佳答案

is it ok to write inline javascript (i.e. add logic) in rails partials?

  • 我的回答是否定的。它不可维护且丑陋。

And what's the best way to write Javascript for maintainable Rails apps?

  • 见下文

你会得到很多基于意见的答案。这个问题确实没有真正的答案。我的回答是 1) 基于意见和 2) 远非完美。

话虽这么说,我想提出我自己的看法。在过去的几年里,我看到并构建了大大小小的 Rails 应用程序(10 个 js 文件的应用程序和 100+ 个应用程序),我对那些应用程序中的 JavaScript 组织以及我所看到的应用程序非常不满意跨 GitHub。我见过无数的 JavaScript 文件,其中充满了无组织和分离的代码。这对我来说似乎不太像 Rails。在过去的几个月里,我一直在努力寻找解决方案,我发现有一个解决方案最接近 Rails 应用程序上组织良好的 JavaScript 代码库。我认为它符合某些 Rails 理想。这种方法的一个缺点是它会在全局范围内乱扔垃圾......我很乐意从 JS 开发人员那里了解如何解决这个问题。

这是中型帖子:

https://medium.com/@cblavier/rails-with-no-js-framework-26d2d1646cd#.36zis335e

我对此做了一些调整,因为有时您需要共享代码,例如,为您的用户提供共享表单的代码。但是,我想把所有的功劳都归功于@cblavier。所以请花点时间阅读他的帖子,因为它包含的重要信息,我不会在下面详细介绍。

要求:Coffeescript、Turbolinks 和 jQuery

# app/helpers/application_helper.rb

def js_class_name
action = case action_name
when 'create' then 'New'
when 'update' then 'Edit'
else action_name
end.camelize

"Views.#{controller_name.camelize}.#{action}View"
end

对于上述帮助器,如果您的应用具有命名空间 Controller ,您将需要考虑命名空间 Controller 。不过那应该相当容易。我认为以下内容可以解决问题。

"Views.#{controller_path.camelize.gsub('::', '.')}.#{action}View"

好的,现在您要将其添加到 <body>在布局中标记。

<body data-class-name="<%= js_class_name %>">

JavaScript 的时间到了!

# initializer.coffee
pageLoad = ->
className = $('body').attr('data-class-name')
initializePage(className)
initializePageBase(className)

initializePage = (className) ->
window.applicationView = try
eval("new #{className}()")
catch error
new Views.ApplicationView()

window.applicationView.render()

initializePageBase = (className) ->
modules = className.split('.')
modules.splice(modules.length - 1, 1)

window.baseView = try
eval("new #{modules.join('.')}.BaseView")

window.baseView.render() unless window.baseView is undefined

$(document).on 'turbolinks:load', pageLoad # turbolinks:load is master branch of turbolinks, if you are using older version, it's page:load
$(document).on 'page:before-change', ->
window.applicationView.cleanup()
true
$(document).on 'page:restore', ->
window.applicationView.cleanup()
pageLoad()
true

# app/assets/javascripts/views/application_view.coffee
window.Views ||= {}

class Views.ApplicationView
render: ->
# pretty much global JS code can be initialized here. It's nice
# to keep the render() method clean though. Like this:
@setupElements()

setupElements: ->
$('[data-toggle=tooltip]').tooltip() # just an example

cleanup: ->

现在您已完成这些设置,是时候开始添加您的页面 JavaScript 了。这里只是页面的一个示例。 users_controller#show

Views.Users ||= {}

class Views.Users.ShowView extends Views.ApplicationView
constructor: ->
# find and cache DOM objects, etc
# ex:
@someButton = $('[data-behavior=expand-user-info]')

render: ->
super() # this is important. It calls render() on ApplicationView

# example stuff
@bindEventListeners()

bindEventListeners: ->
t = this

@someButton.on 'click', ->
t.expandUserInfo()

expandUserInfo: ->
alert('woohoo!')

cleanup: ->
super()

如果您之前注意到,在 initializer.coffee方法,我们调用了一个方法,initializePageBase() .当我使用结构 from that Medium post 时,我遇到了一个问题,我需要在 edit 上使用相同的 javascript和 new意见。那initializePageBase()是解决它的第一步。它将寻找一个 BaseView 类。这是一个例子:

# app/assets/javascripts/views/users/base_view.coffee
Views.Users ||= {}

class Views.Users.BaseView # you don't need to extend ApplicationView here, because we are already initializing it.
render: ->
# code

关于javascript - Rails 前端的最佳实践是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36480221/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com