Coffeescript从列表中动态创建/调用选择框值更改的函数 [英] Coffeescript dynamically create/call a function from a list on select box value change
问题描述
我正在使用 Pixastic库添加一些图像编辑工具。想法是,用户可以从选择框中选择他们想要的图像或工具的一个方面,然后工具将显示在选择框下面(我使用 select2 ),用户可以通过滑块进行编辑。这是我到目前为止:
#这种种子select2选项列表
imageToolsList = [
{ id:'bl',text:'Blur'}
{id:'bc',text:'Brightness / Contrast'}
{id:'ca',text:'Color Adjust '}
...
]
#创建一个选择框,并在框的值更改时调用imageTooler函数
$(。image_tools_select) .each - >
$(@)。select2
placeholder:选择调整工具。
data:imageToolsList
$(@)。on(change,(i) - >
imageTooler JSON.stringify(
val:i.val
clipName:$(@)。closest('。clip')。attr('id')
)
)
#被改变为
imageTooler =(i) - >
imageData = jQuery.parseJSON(i)
iId = imageData.val
imageClipName = imageData.clipName
newTool =< div id =#{iId}> label>#{iId}< / label>< div class ='slider#{iId}'>< / div>< / div>
$(## {imageClipName})。find(。imagetoolfields)。append newTool
$ b b
当选择工具时,在选择框下方附加编辑工具的名称和正确的滑块div,但是我真正想要的是动态地为该特定工具和图像创建一个滑块函数是页面上的多个图像,每个都有自己的编辑工具带)。下面是一个适用于模糊工具的滑块函数:
$('。sliderbl')slider
min:0
max:5
value:0.5
step:0.1
range:min
slide:(event,ui)
$(#img_snapshot_16)。pixastic(blurfast,{amount:ui.value})
有一种方法来扩展imageToolsList,使其看起来像:
imageToolsList = [$ b $ pix {(:;}},sliderVals:{min:0,max(blur,amount:ui.value :5,value:0.5,step:0.1,range:min}}
...
]
,然后为 imageTooler
中的每个工具动态创建jQuery滑块函数,如同使用div和slider div?
注释对于任何复杂的东西来说都有点乏味,所以我会直接进行映射。我已经做了几个假设,什么是定义在哪里和什么时候,但我不认为假设非常重要。
我们将从一个简单的情况开始:只有一个类似于 imageToolsList
中的对象:
b $ b id:'bl'
text:'Blur'
sliderVals:{min:0,max:5,value:0.5,step:0.1,range:min}
tool:(imageClipName) - >
(event,ui) - > $(## {imageClipName})。pixastic(blurfast,{amount:ui.value})
}
我已经调整了一些顺序,并将工具
切换到返回函数的函数。我们不希望在 imageToolsList
中定义对象字面值时发生 pixastic
调用,使 tool
一个函数允许我们推迟 pixastic
执行,直到后来。因为我们(大概)不知道当定义 imageToolsList
时, imageClipName
应该是什么我们再次填充,再次调用 pixastic
直到以后;因此函数返回一个函数技巧。
给定其中一个,我们如何构建一个 slider
我们需要做的是复制 sliderVals
(以避免更改 imageToolsList
)并填写幻灯片
函数:
sliderDef = {id:'bl',...} b doTheSliderThing =(imageClipName) - >
slide = sliderDef.tool(imageClipName)
args = $ .extend({},sliderDef.sliderVals,slide:slide)
$(。slider#{sliderDef.id}) .slider(args)
#让它一切顺利和pixastic-ify`#pancakes`。
doTheSliderThing('pancakes')
工具
是一个返回回调函数的函数,所以 sliderDef.tool(imageClipName)
给我们合适的
(event,ui) - > $(...)。pixastic(...)
回调函数。
如果我们有一个 id
,我们需要从 imageToolList
那么我们必须去寻找它:
#如果列表很短:
[sliderDef] = for a in imageToolList when o.id == id)
for
循环给你一个数组,然后 [sliderDef]
解开该数组,并将单个结果保留 sliderDef
。如果 imageToolList
更长,那么你会想要短路循环,一旦你有结果就释放:
#更长的列表,一旦我们找到了我们要找的东西。
for o in imageToolList when o.id == 2
sliderDef = o
break
或更好,重做 imageToolList
的结构以允许直接访问 id
:
#甚至更长的列表:允许通过`id`直接访问。
imageToolList =
bl:{text:'Blur',sliderVals:{...},...}
...
然后我们可以这样做:
doTheSliderThing =(id,imageClipName) - >
sliderDef = imageToolList [id]
slide = sliderDef.tool(imageClipName)
args = $ .extend({},sliderDef.sliderVals,slide:slide)
$ .slider#{id})。slider(args)
#使用`'bl'`使所有的都去和pixastic-ify`#pancakes`。
doTheSliderThing('bl','pancakes')
terse:
doTheSliderThing =(id,imageClipName) - >
$(。slider#{id})。slider($。extend({}
imageToolList [id] .sliderVals
slide:imageToolList [id] .tool(imageClipName)
))
:如果您有这个:
sliderDefs =
bl:{text:'Blur' ,sliderVals:{...},...}
...
你可以构建slider2想要的东西,如下所示:
opts =({id:k,text:v.text} k,v of sliderDefs)
I'm working on adding some image editing tools using the Pixastic library. The idea is that the user can choose an aspect of the image or tool they want from a select box, then the tool will show up below the select box (I'm using select2) and the user can edit via a slider. Here's what I have so far:
# This seeds the select2 options list
imageToolsList = [
{id: 'bl', text: 'Blur'}
{id: 'bc', text: 'Brightness/Contrast'}
{id: 'ca', text: 'Color Adjust (RGB)'}
...
]
#Creates a select box and calls imageTooler function when the value of the box is changed
$(".image_tools_select").each ->
$(@).select2
placeholder: "Select an adjustment tool."
data: imageToolsList
$(@).on("change", (i) ->
imageTooler JSON.stringify(
val: i.val
clipName: $(@).closest('.clip').attr('id')
)
)
# The function called on the value that the select box is changed to
imageTooler = (i) ->
imageData = jQuery.parseJSON(i)
iId = imageData.val
imageClipName = imageData.clipName
newTool = "<div id=#{iId}><label>#{iId}</label><div class='slider#{iId}'></div></div>"
$("##{imageClipName}").find(".imagetoolfields").append newTool
This succeeds in appending the name of the editing tool and the correct slider div beneath the select box when a tool is chosen, but what I'd really like is dynamically create a slider function for that particular tool and image (there are multiple images on a page, each with their own editing toolbelt). Here's a slider function that works for a the 'Blur' tool:
$('.sliderbl').slider
min: 0
max: 5
value: 0.5
step: 0.1
range: "min"
slide: (event, ui) ->
$("#img_snapshot_16").pixastic("blurfast", {amount:ui.value})
Is there a way to expand the imageToolsList so that it looks something like:
imageToolsList = [
{id: 'bl', text: 'Blur', tool: $("##{imageClipName}").pixastic("blurfast", {amount:ui.value}), sliderVals: {min: 0, max: 5, value: 0.5, step: 0.1, range: "min"} }
...
]
and then dynamically create the jQuery slider functions for each tool in imageTooler
, as is being done with the div and slider div?
Comments get a little tedious for anything complicated so I'll just go ahead and map it all out. I've made a few assumptions about what is defined where and when but I don't think the assumptions matter that much.
We'll start with a simplified case: just one object similar to what you have in imageToolsList
:
{
id: 'bl'
text: 'Blur'
sliderVals: { min: 0, max: 5, value: 0.5, step: 0.1, range: "min" }
tool: (imageClipName) ->
(event, ui) -> $("##{imageClipName}").pixastic("blurfast", {amount:ui.value})
}
I've tweaked the order a little bit and switched tool
to a function which returns a function. We don't want the pixastic
call to happen while you're defining the object literals in imageToolsList
, making tool
a function allows us to defer the pixastic
execution until later. Since we (presumably) don't know what imageClipName
should be when we define imageToolsList
, we need another function to allow us to fill that in with, again, calling pixastic
until even later; hence the function returning a function trick.
Given one of these, how do we build a slider
call? All we need to do is copy sliderVals
(to avoid changing imageToolsList
) and fill in the slide
function:
sliderDef = { id: 'bl', ... }
doTheSliderThing = (imageClipName) ->
slide = sliderDef.tool(imageClipName)
args = $.extend({ }, sliderDef.sliderVals, slide: slide)
$(".slider#{sliderDef.id}").slider(args)
# And make it all go and pixastic-ify `#pancakes`.
doTheSliderThing('pancakes')
tool
is a function which returns a callback function so sliderDef.tool(imageClipName)
gives us the appropriate
(event, ui) -> $(...).pixastic(...)
callback function.
If we have an id
and we want the appropriate entry from imageToolList
, then we have to go looking for it:
# If the list is short:
[sliderDef] = (o for o in imageToolList when o.id == id)
The for
loop gives you an array back and then the [sliderDef]
unwraps that array and leaves the single result in sliderDef
. If the imageToolList
is longer then you'd want to short-circuit the loop and bail out as soon as you have a result:
# Longer list, bail out as soon as we've found what we're looking for.
for o in imageToolList when o.id == 2
sliderDef = o
break
or better, rework the structure of imageToolList
to allow direct access by id
:
# Even longer list: allow direct access by `id`.
imageToolList =
bl: { text: 'Blur', sliderVals: { ... }, ... }
...
and then we can do things like this:
doTheSliderThing = (id, imageClipName) ->
sliderDef = imageToolList[id]
slide = sliderDef.tool(imageClipName)
args = $.extend({ }, sliderDef.sliderVals, slide: slide)
$(".slider#{id}").slider(args)
# And make it all go and pixastic-ify `#pancakes` using `'bl'`.
doTheSliderThing('bl', 'pancakes')
Or, if you prefer to be terse:
doTheSliderThing = (id, imageClipName) ->
$(".slider#{id}").slider($.extend({ }
imageToolList[id].sliderVals
slide: imageToolList[id].tool(imageClipName)
))
Update for the comments: If you have this:
sliderDefs =
bl: { text: 'Blur', sliderVals: { ... }, ... }
...
Then you can build the stuff that slider2 wants like this:
opts = ({id: k, text: v.text} for k,v of sliderDefs)
这篇关于Coffeescript从列表中动态创建/调用选择框值更改的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!