【问题标题】:jquery tmpl in a closurejquery tmpl 在一个闭包中
【发布时间】:2011-06-28 15:27:15
【问题描述】:

我正在开发这个小型 javascript 库,并遵循各种建议,出于各种原因(变量封装、代码隐藏等),我将我的功能包装在一个闭包中。因为我查询 JSON 网络服务并显示结果,所以我还使用 jquery tmpl 引擎。
我想我理解闭包有什么好处,但我肯定不理解它们。这意味着我在所有这些范围变化和诸如此类的事情之间完全迷失了。特别烦人的是我得到的这个例外。考虑以下代码(相关代码的简化丑陋版本,但它重现了问题)

// something would be the object that handles all the library functionality
var something = function(){

    // creating a local function that goes as a parameter into the Array.filter
    function isBar(data){
        return data.name === "bar";
    }

    // the template code
    var bla = "<h1>${name}<\h1><h2>${attribute.filter(isBar)[0].value}</h2>";

    // precompiling the the template
    $.template("test", bla);

    // and returning a function that should render the template with the provided data
    return {
        funny: function(){
            $.tmpl("test", [{"name":"Fo", "attribute":[{"name":"bar", "value":"how"}]},
                            {"name":"Foo", "attribute":[{"name":"fnord","value":"can"}]},
                            {"name":"Fooo", "attribute":[{"name":"bar","value":"this"}]},
                            {"name":"Foooo", "attribute":[{"name":"Bar", "value":"be"}]}
            ]);
        }
    }
}();
// calling the function
something.funny();

因此,当调用 something.funny() 时,我希望会发生以下情况:作为闭包的函数 funny 在其原始上下文中被调用(例如,函数 isBar 和变量 bar 已定义)。所以当我打电话给$.tmpl 时,我希望模板中的attribute.filter(isBar) 也在这个范围内。但事实并非如此。我 Chrome 我得到ReferenceError: isBar is not defined
如果有人愿意向我展示我的错误方式,我会非常高兴。

【问题讨论】:

    标签: javascript closures jquery-templates


    【解决方案1】:

    edit 哎呀我错过了“()”。

    好的,问题是闭包中对局部变量的引用并不是对局部变量的真正引用——它们是字符串的一部分。模板代码必须解析那个字符串,所以当它解析时,在调用“$.tmpl()”的闭包中有一个名为“isBar()”的函数真的无关紧要。 jQuery 无法访问它们,因为您无法在 JavaScript 中这样做。

    但是,您可以将“options”第三个参数传递给“$.tmpl()”并在那里提供额外的东西。我不是 100% 确定该怎么做,因为我只玩了一点模板插件,但是当我有机会时我会尝试一个 jsfiddle。我认为你基本上会做这样的事情:

        funny: function(){
            $.tmpl("test", [{"name":"Fo", "attribute":[{"name":"bar", "value":"how"}]},
                            {"name":"Foo", "attribute":[{"name":"fnord","value":"can"}]},
                            {"name":"Fooo", "attribute":[{"name":"bar","value":"this"}]},
                            {"name":"Foooo", "attribute":[{"name":"Bar", "value":"be"}]}
            ], { isBar: isBar });
        }
    

    我不确定你是在模板文本中将其称为“${isBar()}”还是“${item.isBar()}”。

    【讨论】:

    • 是的,就是这样。我将{isBar: function(data){ return data.name === "bar";} 作为选项参数传递,它可以在模板中引用${$item.isBar()}。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2012-07-19
    • 2011-04-14
    • 2012-11-08
    • 2012-10-06
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多