//>>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.
//
// |
// |
// |
// |
// |
// |
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
}
});
}
});
});