Module: Netzke::Core::Composition
Overview
Any Netzke component can define child components, which can either be statically nested in the compound layout (e.g. as different regions of the ‘border’ layout), or dynamically loaded at a request (as is the advanced search panel in Basepack::GridPanel, for example).
Defining a component
You can define a child component by calling the component
class method which normally requires a block:
component :users do |c|
c.klass = GridPanel
c.model = "User"
c.title = "Users"
end
If no configuration is required, and the component’s class name can be derived from its name, then the block can be omitted, e.g.:
component :user_grid
which is equivalent to:
component :user_grid do |c|
c.klass = UserGrid
end
Overriding a component
When overriding a component, the ‘super` method should be called, with the configuration object passed to it as parameter:
component :users do |c|
super(c)
c.title = "Modified Title"
end
Referring to components in layouts
A child component can be referred in the layout by using symbols:
component :users do |c|
c.title = "A Netzke component"
end
def configure(c)
super
c.items = [
{ xtype: :panel, title: "Simple Ext panel" },
:users # a Netzke component
]
end
If extra (layout) configuration is needed, a component can be referred to by using the component
key in the configuration hash (this can be useful when overriding a layout of a child component):
component :tab_one # ...
component :tab_two # ...
def configure(c)
super
c.items = [
{component: :tab_one, title: "One"},
{component: :tab_two, title: "Two"}
]
end
Lazily vs eagerly loaded components
By default, if a component is not used in the layout, it is lazily loaded, which means that the code for this component is not loaded in the browser until the moment the component gets dynamically loaded by the JavaScript method ‘netzkeLoadComponent` (see ClientCode). Referring a component in the layout (the `items` property) automatically makes it eagerly loaded. Sometimes it’s desired to eagerly load a component without using it directly in the layout (an example can be a window that we need to render instantly without requesting the server). In this case an option ‘eager_load` can be set to true:
component :eagerly_loaded_window, eager_load: true do |c|
c.klass = SomeWindowComponent
end
Dynamic component loading
Child components can be dynamically loaded by using client class’ netzkeLoadComponent
method (see javascript/ext.js for inline documentation):
Excluded components
You can make a child component inavailable for dynamic loading by using the excluded
option. When an excluded component is used in the layout, it will be skipped. This can be used for authorization.
Preventing name clashing with actions
If a component has an action and a child component sharing the name, referring to them by symbols in the configuration will result in a name clash. In that case refer to the child component by a hash, e.g.:
class Dashboard < Netzke::Base
action :users
component :users
def configure(c)
super
c. = [:users]
c.items = [{component: :users}]
end
end
Defined Under Namespace
Modules: ClassMethods
Instance Method Summary collapse
-
#component_config(component_name, overrides = {}) ⇒ Hash
instantiation.
-
#component_instance(name_or_config, overrides = {}) ⇒ Object
Instantiates a child component by its name.
-
#dependency_classes ⇒ Array<Class>
All component classes that we depend on (used to render all necessary javascripts and stylesheets).
-
#eagerly_loaded_components ⇒ Array
Names of eagerly loaded components.
- #extend_item(item) ⇒ Object
Instance Method Details
#component_config(component_name, overrides = {}) ⇒ Hash
instantiation
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/netzke/core/composition.rb', line 159 def component_config(component_name, overrides = {}) return nil if component_name.nil? component_name = component_name.to_sym ComponentConfig.new(component_name, self).tap do |cfg| cfg.client_config = HashWithIndifferentAccess.new(Netzke::Support.permit_hash_params(overrides[:client_config])) cfg.item_id = overrides[:item_id] if respond_to?(:"#{component_name}_component") send("#{component_name}_component", cfg) elsif inline_components[component_name] cfg.merge!(inline_components[component_name]) else return nil end cfg.set_defaults! end end |
#component_instance(name_or_config, overrides = {}) ⇒ Object
Instantiates a child component by its name. params
can contain:
[client_config] a config hash passed from the client class
[item_id] overridden item_id, used in case of loading multiple instances of the same child component
150 151 152 153 154 155 |
# File 'lib/netzke/core/composition.rb', line 150 def component_instance(name_or_config, overrides = {}) cfg = name_or_config.is_a?(Hash) ? name_or_config : component_config(name_or_config, overrides) return nil if cfg.nil? || cfg[:excluded] klass = cfg.klass || cfg.class_name.constantize klass.new(cfg, self) end |
#dependency_classes ⇒ Array<Class>
Returns All component classes that we depend on (used to render all necessary javascripts and stylesheets).
181 182 183 184 185 186 187 188 189 190 |
# File 'lib/netzke/core/composition.rb', line 181 def dependency_classes res = [] eagerly_loaded_components.each do |aggr| res += component_instance(aggr).dependency_classes end res += self.class.netzke_ancestors res.uniq end |
#eagerly_loaded_components ⇒ Array
Returns names of eagerly loaded components.
142 143 144 |
# File 'lib/netzke/core/composition.rb', line 142 def eagerly_loaded_components self.class.eagerly_loaded_dsl_components + @components_in_config end |
#extend_item(item) ⇒ Object
192 193 194 |
# File 'lib/netzke/core/composition.rb', line 192 def extend_item(item) super detect_and_normalize_component(item) end |