我可以使用类似 String#constantize 的东西来初始化 Hyperstack::Component 吗?
Can I use something along the lines of String#constantize to initialize a Hyperstack::Component?
我的数据库中有一些对象,我想使用专用的 Hyperstack 视图组件来呈现这些对象。
假设我的对象从 A 到 J 有一个唯一的 name
属性。现在我想用 each
遍历它们并渲染 ComponentA
, ComponentB
, ComponentC
, ... 取决于我对象的 name
,并将我的对象作为参数传递给组件。
我现在做的是:
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)
,但我发现其他开发人员在参与项目时会感到相当困惑。
请记住 String#constantize
将 return 实际常量,而不仅仅是一个常量化的字符串(驼峰式等等),因此您可以调用 #new
或 #call
或者你想要的任何东西。
每个组件 class 都定义了一个与 class 同名的方法。例如,当您说
ComponentA(data: object)
您正在调用名为 ComponentA
的方法,该方法与 ComponentA class.
相关联
因此,要动态引用组件,您将使用 send
方法:
send('Component' + object.name, data: object)
或者,每个组件 class 都有一个 class 方法 insert_element
,它将渲染组件 class 的一个实例,并将其插入渲染缓冲区。例如:
('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
以外的东西。无论如何,你真的可以玩得开心!
我的数据库中有一些对象,我想使用专用的 Hyperstack 视图组件来呈现这些对象。
假设我的对象从 A 到 J 有一个唯一的 name
属性。现在我想用 each
遍历它们并渲染 ComponentA
, ComponentB
, ComponentC
, ... 取决于我对象的 name
,并将我的对象作为参数传递给组件。
我现在做的是:
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)
,但我发现其他开发人员在参与项目时会感到相当困惑。
请记住 String#constantize
将 return 实际常量,而不仅仅是一个常量化的字符串(驼峰式等等),因此您可以调用 #new
或 #call
或者你想要的任何东西。
每个组件 class 都定义了一个与 class 同名的方法。例如,当您说
ComponentA(data: object)
您正在调用名为 ComponentA
的方法,该方法与 ComponentA class.
因此,要动态引用组件,您将使用 send
方法:
send('Component' + object.name, data: object)
或者,每个组件 class 都有一个 class 方法 insert_element
,它将渲染组件 class 的一个实例,并将其插入渲染缓冲区。例如:
('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
以外的东西。无论如何,你真的可以玩得开心!