/
filtered_collection.coffee
136 lines (116 loc) · 2.83 KB
/
filtered_collection.coffee
1
2
3
4
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
37
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# How would you implement this such that the @parent/@filter property could be changed?
#
# perhaps.. something like this?
#
# @property "parent"
# @property "filter"
# @virtualProperty "parent", "filter",
# models:
# get: ->
# set: ->
# add: ->
# remove: ->
AS = require "alpha_simprini"
Taxi = require "taxi"
{extend, isString, isFunction, isArray} = require "underscore"
AS.FilteredCollection = AS.Collection.extend ({delegate, include, def, defs}) ->
delegate 'add', 'remove', to: 'parent'
# @::initialize.doc =
# params: [
# ["@parent", AS.Collection, true]
# ["conditions", Object, false, default: {}]
# ]
# desc: """
#
# """
def initialize: (@parent, conditions={}) ->
@_super()
@conditions = Taxi.Map.new()
@conditions.set(key, value) for key, value of conditions
@conditions.bind
event: 'change'
handler: @reFilter
context: this
@parent.bind
event: 'add'
handler: @determinePlacementInSelf
context: this
namespace: @objectId()
@parent.bind
event: 'change'
handler: @determinePlacementInSelf
context: this
namespace: @objectId()
@parent.bind
event: 'remove'
handler: @removeFromSelf
context: this
namespace: @objectId()
@reFilter()
# @::determinePlacementInSelf.doc =
# params: [
# ["model", AS.Model, true]
# ]
# desc: """
#
# """
def determinePlacementInSelf: (model) ->
if @filter(model) is true
@addToSelf(model)
else
@removeFromSelf(model)
# @::addToSelf.doc =
# params: [
# [model, AS.Model, true]
# ]
# desc: """
#
# """
def addToSelf: (model) ->
return if @models.include(model).value()
@_add(model)
# @::removeFromSelf.doc =
# params: [
# [model, AS.Modle, true]
# ]
# desc: """
#
# """
def removeFromSelf: (model) ->
return unless @models.include(model).value()
@_remove(model)
# @::reFilter.doc =
# desc: """
#
# """
def reFilter: ->
@parent.each (model) => @determinePlacementInSelf(model)
# @::setConditions.doc =
# params: [
# ["conditions", Object, true]
# ]
# desc: """
#
# """
def setConditions: (conditions) ->
@conditions.unbind()
@conditions.set(key, value) for key, value of conditions
@conditions.bind
event: 'change'
handler: @reFilter
context: this
@reFilter()
# @::filter.doc =
# params: [
# ["model", AS.Model, true]
# ]
# desc: """
#
# """
def filter: (model) ->
for key, value of @conditions.toObject()
modelValue = model[key].get()
testValue = if isFunction(value) then value.call() else value
testValue = if isArray(testValue) then testValue else [testValue]
return false unless modelValue in testValue
true