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