Rails、CoffeeScript- 使用class进行封装以进行命名空间管理
过程
-
- グローバルで変数名が衝突しないよう、ネームスペース・モジュール管理をやるべきらしい。
-
- JSは多用しないので、可能であればRailsサイドで解決したい。
- 今後は意識して実践していきたいのでメモ。
方法
在进行调查时,发现有很多种方法,但是我喜欢这种方法。
创建一个或多个用于命名空间的目录。
/javascripts
/namespace # ネームスペース用のディレクトリー
base.coffee
charts.coffee
moving_items.coffee
[..]
application.js
namespace.js # ネームスペース設定ファイル
请将命名空间加载到资产管道中
//= require jquery
//= require jquery_ujs
//= require jquery.turbolinks
//= require bootstrap
//= require turbolinks
//...
//= require namespace
//= require ./namespace/base
//= require_tree ./namespace
在base文件中准备命名空间对象。
@Namespace = {}
# $(document).on "ready page:load", ->
# $('a[href^="/documents/"]').attr('target', '_blank')
将JS代码包装在命名空间下的类中
在等待实例化之前,类内的代码将会被暂时搁置。
构造函数返回某个值的例子。
# Chart.js configuration
Chart.defaults.global.tooltipEvents = ["mousemove", "touchstart", "touchmove"]
Chart.defaults.global.scaleLabel = "<%=value%>cu.ft"
class @Components.ChartComponent
constructor: (chartType)->
return @createClass(chartType)
createClass: (chartType) ->
React.createClass
displayName: "#{chartType}Chart"
propTypes:
name: React.PropTypes.string
data: React.PropTypes.oneOfType([React.PropTypes.array, React.PropTypes.object])
height: React.PropTypes.number
width: React.PropTypes.number
options: React.PropTypes.object
getInitialState: ->
chartInstance: null
render: ->
React.DOM.canvas
ref: @props.name
style: { height: @props.height, width: @props.width }
componentDidMount: ->
@initializeChart()
componentWillUnmount: ->
@state.chartInstance.destroy() if @state.chartInstance
initializeChart: ->
canvas = React.findDOMNode(@refs[@props.name])
ctx = canvas.getContext("2d")
chart = new Chart(ctx)[chartType](@props.data)
@setState.chartInstance = chart
以下是使用构造函数注册事件监听器的例子。
# moving_items/new, moving_items/edit
class @Namespace.MovingItems
constructor: ->
setVolume = (volume) -> $("#moving_item_volume").val(volume)
setSlider = (volume) -> $("#volume_slider").val(volume)
# Slider
document.getElementById('volume_slider').addEventListener 'change', ->
setVolume(document.getElementById('volume_slider').value)
# AutoComplete
$('#moving_item_name').autocomplete
source: Object.keys( $('#suggestions').data('items') )
select: (e, ui) =>
itemVolume = $('#suggestions').data('items')[ui.item.value]
setVolume(itemVolume)
setSlider(itemVolume)
$('#moving_item_room').autocomplete
source: $('#suggestions').data('rooms')
$('#moving_item_category').autocomplete
source: $('#suggestions').data('categories')
使用HAML的:coffee滤镜来调用并实例化JS代码。
:coffee
window.BarChartComponent = new Namespace.ChartComponent("Bar")
window.PieChartComponent = new Namespace.ChartComponent("Pie")
.panel.panel-blue
.panel-heading
/...
- if @total_volume > 0
.panel-body
.row
.col-sm-6
= react_component 'BarChartComponent', { name: "MovingBarChart",
data: @dataForBarChart, height: 200, width: 400 }
.col-sm-6
= react_component 'PieChartComponent', { name: "MovingPieChart",
data: @dataForPieChart, height: 200, width: 200 }
在(:javascript)中,也可以使用content_for(:javascript)和yield(:javascript)来实现相同的效果。
!!!
%html
%head
/...
%body
= yield # ページコンテンツ
/...
= yield(:javascript) # 必要なJSコードを生成する
- content_for(:javascript) do
:coffeescript
jQuery ->
window.BarChartComponent = new Namespace.ChartComponent("Bar")
window.PieChartComponent = new Namespace.ChartComponent("Pie")
/...
信息
-
- Essential JavaScript Namespacing Patterns
-
- JavaScript Namespacing with the Rails Asset Pipeline
-
- Write maintainable JavaScript/CoffeeScript in Rails
- CoffeeScriptのclassをグローバルに定義する。