Coffeescript从列表中动态创建/调用选择框值更改的函数 [英] Coffeescript dynamically create/call a function from a list on select box value change

查看:221
本文介绍了Coffeescript从列表中动态创建/调用选择框值更改的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆