[英]Can I use something along the lines of String#constantize to initialize a Hyperstack::Component?
我的数据库中有一些对象,我想使用专用的Hyperstack视图组件进行渲染。 假设我的对象具有从A到J的唯一name
属性。现在,我想遍历它们的each
对象,并根据对象的name
呈现ComponentA
, ComponentB
, ComponentC
,...,并将我的对象作为组件的参数。
我现在要做的是:
DB_Objects.each do |object|
if object.name == 'A'
ComponentA(data: object)
elsif object.name == 'B'
ComponentB(data: object)
elsif object.name == 'C'
ComponentC(data: object)
elsif ...
我想做的是这样的:
DB_Objects.each do |object|
('Component' + object.name).constantize(data: object)
end
这是伪代码,因为您不能给变量提供常量。 但这显示了我想做的事。
如何防止将对象手动映射到其视图。
从未使用过HyperStack,但这应该给您正确的想法。
class Thing < ApplicationRecord
OBJECT_TYPES = { 'A': 'CommponentA' }.freeze
def to_component
@to_component ||= OBJECT_TYPES[self.name].constantize.new(self)
end
end
您可以只使用"Component#{self.name}".constantize.new(self)
但我发现,当其他开发人员进入某个项目时,这"Component#{self.name}".constantize.new(self)
他们感到困惑。
请记住, String#constantize
将返回实际的常量,而不仅仅是返回一个已常#new
的字符串(驼峰式以及您所拥有的),因此您可以调用#new
或#call
或任何您想要的#call
。
每个组件类都定义一个与该类同名的方法。 当你说例如
ComponentA(data: object)
您正在调用一个与ComponentA类绑定的名为ComponentA
的方法。
因此,要动态引用组件,可以使用send
方法:
send('Component' + object.name, data: object)
另外,每个组件类都有一个类方法insert_element
,它将渲染该组件类的一个实例,并将其插入到渲染缓冲区中。 例如:
('Component' + object.name).constantize.insert_element(data: object)
我提出这一点是因为它虽然更长,但是您可以使用它来概括您的想法(我认为这很酷)
class ApplicationRecord < ActiveRecord::Base
def render(opts = {})
('Component' + object.name).constantize.insert_element(opts, data: object)
end
end
现在你可以说
some_record.render
当然,要像这样概括它,您可能要使用name
以外的其他name
。 无论如何,您真的可以从中获得乐趣!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.