Module: Netzke::Core::Composition

Extended by:
ActiveSupport::Concern
Included in:
Base
Defined in:
lib/netzke/core/composition.rb

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.bbar = [:users]
    c.items = [{component: :users}]
  end
end

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#component_config(component_name, overrides = {}) ⇒ Hash

instantiation

Returns:

  • (Hash)

    Given component's name and overrides, returns complete component's config, ready for



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/netzke/core/composition.rb', line 153

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(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


144
145
146
147
148
149
# File 'lib/netzke/core/composition.rb', line 144

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_classesArray<Class>

Returns All component classes that we depend on (used to render all necessary javascripts and stylesheets)

Returns:

  • (Array<Class>)

    All component classes that we depend on (used to render all necessary javascripts and stylesheets)



175
176
177
178
179
180
181
182
183
184
# File 'lib/netzke/core/composition.rb', line 175

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_componentsArray

Returns names of eagerly loaded components

Returns:

  • (Array)

    names of eagerly loaded components



136
137
138
# File 'lib/netzke/core/composition.rb', line 136

def eagerly_loaded_components
  self.class.eagerly_loaded_dsl_components + @components_in_config
end

#extend_item(item) ⇒ Object



186
187
188
# File 'lib/netzke/core/composition.rb', line 186

def extend_item(item)
  super detect_and_normalize_component(item)
end