1

嘿,现在我正在使用 jQuery,并且我有一些全局变量来保存一些预加载的 ajax 内容(预加载以使页面变得又好又快):


$.get("content.py?pageName=viewer", function(data)
    {viewer = data;});
$.get("content.py?pageName=artists", function(data)
    {artists = data;});
$.get("content.py?pageName=instores", function(data)
    {instores = data;});
$.get("content.py?pageName=specs", function(data)
    {specs = data;});
$.get("content.py?pageName=about", function(data)
    {about = data;});

如您所见,我们严重违反了 DRY 原则,但是……我真的没有办法解决它……有什么想法吗?

也许是一个数组?

4

6 回答 6

6

使用 jQuery each 方法遍历页面名称数组,然后设置全局(在窗口范围内)变量:

jQuery.each(
    ["viewer", "artists", "instores", "specs", "about"],
    function (page) {
        $.get("content.py?pageName=" + page,
            new Function("window[" + page + "] = arguments[0]"));
    }
);

更新:实际上,您甚至不需要“新功能”:

jQuery.each(
    ["viewer", "artists", "instores", "specs", "about"],
    function (page) {
        $.get("content.py?pageName=" + page, function () { window[page] = arguments[0]; });
    }
);
于 2008-10-14T16:46:11.010 回答
5

你不需要eval()Function()为此。正如您所怀疑的,一个数组会很好地完成这项工作:

(function() // keep outer scope clean
{
   // pages to load. Each name is used both for the request and the name
   // of the property to store the result in (so keep them valid identifiers
   // unless you want to use window['my funky page'] to retrieve them)
   var pages = ['viewer', 'artists', 'instores', 'specs', 'about'];

   for (var i=0; i<pages.length; ++i)
   {
      // "this" refers to the outer scope; likely the window object. 
      // And will result in page contents being stored in global variables 
      // with the same names as the pages being loaded. We use the with({})
      // construct to create a local scope for each callback with the
      // appropriate context and page name.
      with ({context: this, pageName: pages[i]})
         $.get("content.py?pageName=" + pageName, function(data)
            {context[pageName] = data;});
   }

})(); // close scope, execute anonymous function

// at this point, viewer, artists, etc. are populated with page contents 
// (assuming all requests completed successfully)
于 2008-10-14T17:06:02.077 回答
2

您可以避免使用新功能进行评估:

var names = ['viewer', 'artists', 'instores', 'specs', 'about'];
for (var i = 0; i < names.length; i++)
   $.get("content.py?pageName=" + names[i], new Function('data', names[i] + ' = data;'));

虽然tbh并没有好很多

于 2008-10-14T16:19:26.943 回答
0

您只能在该页面调用一次,并返回一个 json 对象而不是文本

{
viewer:'me',
artists:'you',
instores:'instores',
specs:'specs',
about:'about'
}

并评估,因为现在你调用了 N 次你的服务器,这会减慢所有速度,你应该重新考虑你的逻辑!

PS。在我写的时候,我看到了 RoBorg 的答案,你看,当你使用新函数时,你在后台使用 eval,所以如果你想使用它,就去吧(在某些浏览器中也更快)

于 2008-10-14T16:35:22.200 回答
0

这不使用 eval,虽然它有点罗嗦。

function get_content(name){
   $.get("content.py?pageName=" + name, function(data){ window[name] = data;});
}

var names = ['viewer', 'artists', 'instores', 'specs', 'about'];
for (var i = 0; i < names.length; i++)
    get_content(names[i]);

但是其中一位回答者提出了一个很好的观点,您可能应该尝试将所有这些请求合并为一个,否则您的服务器将针对页面的每个请求的动态内容被命中 6 次。

于 2008-10-14T17:17:35.737 回答
0

这些建议的解决方案中的大多数都避免使用eval。Doduglas Crockford 的“ JavaScript 编程语言的代码约定”进一步强化了这种做法,其中部分内容是

“评估是邪恶的

eval 函数是 JavaScript 中被滥用最多的特性。躲开它。

eval 有别名。不要使用 Function 构造函数。”

于 2008-10-17T13:41:02.393 回答