我正在开发一个 jQuery 插件。当插件运行时,它做的第一件事就是确定它的设置。它通过采用一些默认设置并使用用户传入的任何内容覆盖其中的部分或全部来实现此目的。
这是一个简化的版本:
(function( $ ) {
$.fn.somePlugin = function(userOptions) {
// Short name for internal use - exposed below for external modification
var defaults = $.fn.somePlugin.defaults;
// Decide settings
// User settings overrule defaults, but merge both into an empty
// hash so that original defaults hash isn't modified
var settings = $.extend(true, {}, defaults, userOptions);
settings.alerter.call();
// More code, etc.
}
$.fn.somePlugin.defaults = {
name: 'Captain Slappy von Martinez, Esquire, DDS',
favoriteColor: 'red',
alerter: function(){alert("I got bones!");}
}
})( jQuery );
所以,如果你这样调用插件:
$('div').somePlugin({alerter: function(){alert('No bones here!');}});
...您覆盖默认的 alerter 函数,但使用默认的 favoriteColor。
我在插件本身之外定义默认值,以便可以公开访问它们。因此,如果您想更改 favoriteColor 的默认 值,您可以这样做:
$.fn.somePlugin.defaults.favoriteColor = 'blue';
... 之后页面上的每个实例都会更改它。
所有这些工作正常。
这是我的问题:在其中一个默认功能中,我需要引用settings。像这样:
$.fn.somePlugin.defaults = {
name: 'Captain Slappy von Martinez, Esquire, DDS',
favoriteColor: 'red',
alerter: function(){alert("Paint me " + settings.favoriteColor);}
}
但是当我尝试这样做时,我在声明默认警报器函数的行上收到一个 Javascript 错误:“未定义设置。”确实如此:当解析器命中该行时,它还没有定义。它将在函数运行时定义,但这似乎无关紧要。
所以我的问题是:如何将我的默认函数导入到插件中,使其可以访问settings?
settings 的评估延迟到实际调用该函数之前?someFunction.call(valueToUseForThis) 改变函数内部 this 的值,但我不知道我是否可以在事实上。settings,就可以使用默认设置。但是在那里声明它会导致问题:如果我在一个页面上多次使用我的插件,实例的设置就会混淆。最佳答案
任何事后更改范围的尝试都注定要失败。 JavaScript 中没有动态作用域。
解决方法 1. 将设置显式传递给警报器:
$.fn.somePlugin = function(userOptions) {
var settings = $.extend(...);
settings.alerter(settings)
}
$.fn.somePlugin.defaults = {
favoriteColor: 'red',
alerter: function(settings) { alert("Paint me " + settings.favoriteColor) }
}
解决方法 2. 将设置隐式传递给警报器:
$.fn.somePlugin = function(userOptions) {
var settings = $.extend(...);
settings.alerter()
}
$.fn.somePlugin.defaults = {
favoriteColor: 'red',
alerter: function() { alert("Paint me " + this.favoriteColor) }
}
这两种解决方案都经过测试,并且可以很好地与插件的多次使用配合使用。如果您不打算在警报器中使用 this 关键字,则可以将其用于引用设置。
您和 fudgey 提到的第三个有效解决方案是将设置对象附加到 DOM 元素本身:
$.fn.somePlugin = function(userOptions) {
var settings = $.extend(...);
$(this).data('somePlugin', {settings: settings})
settings.alerter.call(this)
}
$.fn.somePlugin.defaults = {
favoriteColor: 'red',
alerter: function() {
alert("Paint me " + $(this).data('somePlugin').settings.favoriteColor)
}
}
额外的乐趣。模拟动态作用域,a.k.a 不要这样做
function dynamic(fn) {
var parts = fn.toString().split('{')
fn = parts.shift() + '{ with (args) { ' + parts.join('{') + '}'
return {bind: function(args) { return eval('(' + fn + ')') }}
}
a = b = c = 0
function adder(c) {
alert(a + b + c)
}
dynamic(adder).bind({a: 1, b: 2})(3) // alert(6)
在插件中的使用:
$.fn.somePlugin = function(userOptions) {
var settings = $.extend(...);
dynamic(settings.alerter).bind({settings: settings})()
}
$.fn.somePlugin.defaults = {
favoriteColor: 'red',
alerter: function() { alert("Paint me " + settings.favoriteColor) }
}
关于javascript - 如何让插件的默认设置访问最终设置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5015838/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack