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
|
//>>built
define("dojox/mvc/Repeat", [
"dojo/_base/declare",
"dojo/dom",
"./_Container"
], function(declare, dom, _Container){
/*=====
declare = dojo.declare;
dom = dojo.dom;
_Container = dojox.mvc._Container;
=====*/
return declare("dojox.mvc.Repeat", [_Container], {
// summary:
// A model-bound container which binds to a collection within a data model
// and produces a repeating user-interface from a template for each
// iteration within the collection.
//
// description:
// A repeat is bound to an intermediate dojo.Stateful node corresponding
// to an array in the data model. Child dijits or custom view components
// inside it inherit their parent data binding context from it.
// index: Integer
// An index used to track the current iteration when the repeating UI is
// produced. This may be used to parameterize the content in the repeat
// template for the current iteration.
//
// For example, consider a collection of search or query results where
// each item contains a "Name" property used to prime the "Results" data
// model. Then, the following CRUD-style UI displays all the names in
// the search results in text boxes where they may be updated or such.
//
// | <div dojoType="dojox.mvc.Repeat" ref="Results">
// | <div class="row" dojoType="dojox.mvc.Group" ref="${this.index}">
// | <label for="nameInput${this.index}">Name:</label>
// | <input dojoType="dijit.form.TextBox" id="nameInput${this.index}" ref="'Name'"></input>
// | </div>
// | </div>
index : 0,
// summary:
// Override and save template from body.
postscript: function(params, srcNodeRef){
this.srcNodeRef = dom.byId(srcNodeRef);
if(this.srcNodeRef){
if(this.templateString == ""){ // only overwrite templateString if it has not been set
this.templateString = this.srcNodeRef.innerHTML;
}
this.srcNodeRef.innerHTML = "";
}
this.inherited(arguments);
},
////////////////////// PRIVATE METHODS ////////////////////////
_updateBinding: function(name, old, current){
// summary:
// Rebuild repeating UI if data binding changes.
// tags:
// private
this.inherited(arguments);
this._buildContained();
},
_buildContained: function(){
// summary:
// Destroy any existing contained view, recreate the repeating UI
// markup and parse the new contents.
// tags:
// private
// TODO: Potential optimization: only create new widgets for insert, only destroy for delete.
this._destroyBody();
this._updateAddRemoveWatch();
var insert = "";
for(this.index = 0; this.get("binding").get(this.index); this.index++){
insert += this._exprRepl(this.templateString);
}
var repeatNode = this.srcNodeRef || this.domNode;
repeatNode.innerHTML = insert;
// srcNodeRef is used in _createBody, so in the programmatic create case where repeatNode was set
// from this.domNode we need to set srcNodeRef from repeatNode
this.srcNodeRef = repeatNode;
this._createBody();
},
_updateAddRemoveWatch: function(){
// summary:
// Updates the watch handle when binding changes.
// tags:
// private
if(this._addRemoveWatch){
this._addRemoveWatch.unwatch();
}
var pThis = this;
this._addRemoveWatch = this.get("binding").watch(function(name,old,current){
if(/^[0-9]+$/.test(name.toString())){
if(!old || !current){
pThis._buildContained();
} // else not an insert or delete, will get updated in above
}
});
}
});
});
|