Class: Volt::IfBinding

Inherits:
BaseBinding show all
Defined in:
lib/volt/page/bindings/if_binding.rb

Instance Attribute Summary

Attributes inherited from BaseBinding

#binding_name, #context, #target

Instance Method Summary collapse

Methods inherited from BaseBinding

#dom_section, #remove_anchors

Constructor Details

#initialize(page, target, context, binding_name, branches) ⇒ IfBinding

Returns a new instance of IfBinding.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/volt/page/bindings/if_binding.rb', line 5

def initialize(page, target, context, binding_name, branches)
  super(page, target, context, binding_name)

  getter, template_name = branches[0]

  @branches  = []
  @listeners = []

  branches.each do |branch|
    getter, template_name = branch

    if getter.present?
      value = getter
    else
      # A nil value means this is an unconditional else branch, it
      # should always be true
      value = true
    end

    @branches << [value, template_name]
  end

  # The promise dependency can be invalidated when we need to rerun the update
  # manually because a promise resolved.
  @promise_dependency = Dependency.new

  @computation = -> do
    @promise_dependency.depend

    update
  end.watch!
end

Instance Method Details

#removeObject



96
97
98
99
100
101
102
103
# File 'lib/volt/page/bindings/if_binding.rb', line 96

def remove
  @computation.stop if @computation
  @computation = nil

  @template.remove if @template

  super
end

#updateObject



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/volt/page/bindings/if_binding.rb', line 38

def update
  # Find the true branch
  true_template = nil
  @branches.each do |branch|
    value, template_name = branch

    if value.is_a?(Proc)
      begin
        current_value = @context.instance_eval(&value)

        if current_value.is_a?(Promise)
          # If we got a promise, use its value if resolved.
          if current_value.resolved?
            # Should call then immediately
            current_value.then do |value|
              current_value = value
            end
          else
            # if its not, resolve it and try again.
            # TODO: we maybe could cache this so we don't have to run a full update again
            current_value.then do |val|
              # Run update again
              @promise_dependency.changed!
            end

            current_value = nil
          end
        end
      rescue => e
        Volt.logger.error("IfBinding:#{object_id} error: #{e.inspect}\n" + `value.toString()`)
        current_value = false
      end
    else
      current_value = value
    end

    if current_value && !current_value.is_a?(Exception)
      # This branch is currently true
      true_template = template_name
      break
    end
  end

  # Change out the template only if the true branch has changed.
  if @last_true_template != true_template
    @last_true_template = true_template

    if @template
      @template.remove
      @template = nil
    end

    if true_template
      @template = TemplateRenderer.new(@page, @target, @context, binding_name, true_template)
    end
  end
end