这是我关于 SO 的第一个问题,希望我没有搞砸。 我已经检查了关于这个问题的其他主题,但它们没有涵盖我遇到的情况。
我正在 Backbone 之上构建一个库来创建移动应用程序。 我将所有组件定义为主干 View 的主要原因是因为我想在滚动时进行内存优化(隐藏内容/从 DOM 中删除内容)。
让我先从最理想的防御开始
定义一个基类供其他组件使用,有一些默认 我需要在每个组件上使用的属性和一些方便的方法。
UI.Component = Backbone.View.extend({
viewOptions: ['children'],
children: [],
add: function(child) {
this.children.push(child);
}
});
定义一个具有一些默认属性的组件
UI.Header = UI.Component.extend({
viewOptions: ['titleBarChildren', 'secondaryBarChildren', 'title', 'backButtonTitle'],
titleBarChildren: [],
secondaryBarChildren: [],
title: '',
backButtonTitle: 'Back'
});
制作一个在我的应用程序中使用的默认 header
MyApp.Headers.Default = UI.Header.extend({
backButtonTitle: 'Terug',
titleBarChildren: [
new UI.SegmentedController({
children: [
new UI.Button('Lame example')
]
})
]
});
使用我的导航栏
var homePageNavbar = new MyApp.Header.Default({
title: 'Homepage'
});
现在开始吧
console.log(homePageNavbar);
想象一下我们得到了这个输出
// My properties, all nicely inherited
viewOptions: Array[5] //['children', 'titleBarChildren', 'secondaryBarChildren', 'title', 'backButtonTitle']
children: Array[0],
titleBarChildren: Array[1],
secondaryBarChildren: Array[0],
title: "Homepage",
backButtonTitle: "Terug"
// Some stuff that backbone assigns
$el: jQuery.fn.jQuery.init[1]
cid: "view12"
el: HTMLDivElement
options: Object
__proto__: ctor
这就是我最终想要得到的结果,但这需要一些超出我经验的魔法。
附带说明一下,我曾尝试对所有自定义内容使用“选项”属性,但问题是当我创建多个 View 实例时,选项是“共享的”/互相引用。
所以现在我希望我能通过“viewOptions”方法获得更多运气,然后覆盖 _configure method
最好这一切都在 UI.Component 或其子组件中完成。 我不希望此库的用户在其 header 定义 (MyApp.Headers.Default = UI.Header.extend) 中添加一些“样板代码”以扩展选项或其他内容。
现在我必须以某种方式从所有“后代”中获取所有属性。我完全不知道该怎么做。 我已经尝试了解 Backbone 幕后发生的事情,但我无法全神贯注。
因此非常感谢完成此操作的提示/技巧,也非常欢迎替代方法或不符合我的确切要求的方法。
编辑 1
看起来我有一些“有点”有用的东西,这是它的样子
我覆盖了 _configure 方法,将选项添加到实例上,注意 this.getDefaultOptions() 作为 _.extend 中的第一个参数
UI.Component = Backbone.View.extend({
_configure: function(options) {
var viewOptions = this.viewOptions;
options = _.extend(this.getDefaultOptions ? this.getDefaultOptions() : {}, this.options || {}, options || {});
for (var i = 0, l = viewOptions.length; i < l; i++) {
var attr = viewOptions[i];
if (options[attr]) this[attr] = options[attr];
}
this.options = options;
}
});
我将这个新方法添加到我的所有组件中,并且没有将“共享”属性放入我的基础对象 (UI.Component) 中,因为我无法很好地发挥它。
UI.Header = UI.Component.extend({
viewOptions: ['children', 'backButtonTitle', 'title'],
getDefaultOptions: function() {
return {
children: []
};
},
});
现在,我使用类似这样的东西来定义我的标题
MyApp.Headers.Default = UI.Header.extend({
options: {
backButtonTitle: 'Terug',
titleBarChildren: [
new UI.SegmentedController({
children: [
new UI.Button('Lame example')
]
})
]
}
});
我会保持现在的状态,看看这个“解决方案”是否存在,并会报告。 如果您认为自己有更好的答案,请不要犹豫发布 =)
编辑
这是我最新的方法,使用jQuery的深拷贝,看起来还可以
var UI = {};
var App = {
Headers: {}
};
UI.Component = Backbone.View.extend({
blockDefaults: {
children: []
},
initialize: function(options) {
var combinedDefaultsAndOptions = $.extend(true, {}, this.blockDefaults || {}, this.defaults || {}, this.options || {}, options || {});
_.defaults(this, combinedDefaultsAndOptions);
}
});
UI.Header = UI.Component.extend({
defaults: {
backButton: null,
backButtonTitle: null,
secondaryBarChildren: []
}
});
App.Headers.Default = UI.Header.extend({
options: {
backButtonTitle: "App back",
secondaryBarChildren: ["App child"]
}
});
var header1 = new UI.Header({
backButtonTitle: "Header 1 Back",
secondaryBarChildren: ["Header 1 child"]
});
var header2 = new UI.Header({
backButtonTitle: "Header 2 Back",
secondaryBarChildren: ["Header 2 child"]
});
var header3 = new App.Headers.Default({
});
var header4 = new App.Headers.Default({
backButtonTitle: "Overrided App Back"
});
header1.secondaryBarChildren.push('a child for header 1');
console.log(header1, header2, header3, header4);
最佳答案
我认为您想为您的示例覆盖初始化函数,但您有很多事情要做,所以我不确定;如果关闭,请原谅我。我可能只是在清理我认为您正在尝试做的事情,使其成为一个更“ Backbone ”风格的系统。
像这样从你的基础组件开始:
UI.Component = Backbone.View.extend({
defaults : { 'children' : [] },
initialize : function (options) {
_.defaults(options, this.defaults);
_.keys(this.defaults).forEach(function(key) {
this[key] = this.options[key];
}.bind(this));
Backbone.View.prototype.initialize.call(this, options);
},
add: function(child) {
this.children.push(child);
}
});
然后你可以像这样继续扩展它们:
UI.Header = UI.Component.extend({
defaults : {
'titleBarChildren' : [],
'secondaryBarChildren' : [],
'title' : '',
'backButtonTitle' : 'Back'
},
initialize : function (options) {
_.defaults(options, this.defaults);
_.keys(this.defaults).forEach(function(key) {
this[key] = this.options[key];
}.bind(this));
UI.Component.prototype.initialize.call(this, options);
}
});
这是我在代码中尝试做的事情的细目:
Defaults 创建一个干净地保存所有默认属性的对象
defaults : { 'children' : [] },
Initialize 覆盖允许您继续在 View 之间传递选项,但每个组件都使用您的 defaults 对象来填补空白。
initialize : function (options) {
// merges your defaults in with the options passed
_.defaults(options, this.defaults);
// loop through your required defaults for this view
// assigning the attributes to the passed options
_.keys(this.defaults).forEach(function(key) {
this[key] = this.options[key];
}.bind(this));
// Finally pass all your options up the chain of inheritance
UI.Component.prototype.initialize.call(this, options);
},
关于javascript - 以干净的方式扩展主干 View 和继承选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13479571/
我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R
我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c
question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co