source: Dev/trunk/src/client/dojox/app/ViewBase.js

Last change on this file was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

  • Property svn:executable set to *
File size: 7.4 KB
Line 
1define(["require", "dojo/when", "dojo/on", "dojo/dom-attr", "dojo/dom-style", "dojo/_base/declare", "dojo/_base/lang",
2        "dojo/Deferred", "./utils/model", "./utils/constraints"],
3        function(require, when, on, domAttr, domStyle, declare, lang, Deferred, model, constraints){
4        return declare("dojox.app.ViewBase", null, {
5                // summary:
6                //              View base class with model & controller capabilities. Subclass must implement rendering capabilities.
7                constructor: function(params){
8                        // summary:
9                        //              Constructs a ViewBase instance.
10                        // params:
11                        //              view parameters, include:
12                        //
13                        //              - app: the app
14                        //              - id: view id
15                        //              - name: view name
16                        //              - parent: parent view
17                        //              - controller: view controller module identifier
18                        //              - children: children views
19                        this.id = "";
20                        this.name = "";
21                        this.children = {};
22                        this.selectedChildren = {};
23                        this.loadedStores = {};
24                        // private
25                        this._started = false;
26                        lang.mixin(this, params);
27                        // mixin views configuration to current view instance.
28                        if(this.parent.views){
29                                lang.mixin(this, this.parent.views[this.name]);
30                        }
31                },
32
33                // start view
34                start: function(){
35                        // summary:
36                        //              start view object.
37                        //              load view template, view controller implement and startup all widgets in view template.
38                        if(this._started){
39                                return this;
40                        }
41                        this._startDef = new Deferred();
42                        when(this.load(), lang.hitch(this, function(){
43                                // call setupModel, after setupModel startup will be called after startup the loadViewDeferred will be resolved
44                                this._createDataStore(this);
45                                this._setupModel();
46                        }));
47                        return this._startDef;
48                },
49
50                load: function(){
51                        var vcDef = this._loadViewController();
52                        when(vcDef, lang.hitch(this, function(controller){
53                                if(controller){
54                                        lang.mixin(this, controller);
55                                }
56                        }));
57                        return vcDef;
58                },
59
60                _createDataStore: function(){
61                        // summary:
62                        //              Create data store instance for View specific stores
63                        //
64                        // TODO: move this into a common place for use by main and ViewBase
65                        //
66                        if(this.parent.loadedStores){
67                                lang.mixin(this.loadedStores, this.parent.loadedStores);
68                        }
69
70                        if(this.stores){
71                                //create stores in the configuration.
72                                for(var item in this.stores){
73                                        if(item.charAt(0) !== "_"){//skip the private properties
74                                                var type = this.stores[item].type ? this.stores[item].type : "dojo/store/Memory";
75                                                var config = {};
76                                                if(this.stores[item].params){
77                                                        lang.mixin(config, this.stores[item].params);
78                                                }
79                                                // we assume the store is here through dependencies
80                                                try{
81                                                        var storeCtor = require(type);
82                                                }catch(e){
83                                                        throw new Error(type+" must be listed in the dependencies");
84                                                }
85                                                if(config.data && lang.isString(config.data)){
86                                                        //get the object specified by string value of data property
87                                                        //cannot assign object literal or reference to data property
88                                                        //because json.ref will generate __parent to point to its parent
89                                                        //and will cause infinitive loop when creating StatefulModel.
90                                                        config.data = lang.getObject(config.data);
91                                                }
92                                                if(this.stores[item].observable){
93                                                        try{
94                                                                var observableCtor = require("dojo/store/Observable");
95                                                        }catch(e){
96                                                                throw new Error("dojo/store/Observable must be listed in the dependencies");
97                                                        }
98                                                        this.stores[item].store = observableCtor(new storeCtor(config));
99                                                }else{
100                                                        this.stores[item].store = new storeCtor(config);
101                                                }
102                                                this.loadedStores[item] = this.stores[item].store; // add this store to loadedStores for the view                                                       
103                                        }
104                                }
105                        }
106                },
107
108                _setupModel: function(){
109                        // summary:
110                        //              Load views model if it is not already loaded then call _startup.
111                        // tags:
112                        //              private
113                                               
114                        if(!this.loadedModels){
115                                var createPromise;
116                                try{
117                                        createPromise = model(this.models, this.parent, this.app);
118                                }catch(e){
119                                        throw new Error("Error creating models: "+e.message);
120                                }
121                                when(createPromise, lang.hitch(this, function(models){
122                                        if(models){
123                                                // if models is an array it comes from dojo/promise/all. Each array slot contains the same result object
124                                                // so pick slot 0.
125                                                this.loadedModels = lang.isArray(models)?models[0]:models;
126                                        }
127                                        this._startup();
128                                }),
129                                function(err){
130                                        throw new Error("Error creating models: "+err.message);                                 
131                                });
132                        }else{ // loadedModels already created so call _startup
133                                this._startup();                               
134                        }               
135                },
136
137                _startup: function(){
138                        // summary:
139                        //              startup widgets in view template.
140                        // tags:
141                        //              private
142
143                        this._initViewHidden();
144                        this._needsResize = true; // flag used to be sure resize has been called before transition
145
146                        this._startLayout();
147                },
148
149                _initViewHidden: function(){
150                        domStyle.set(this.domNode, "visibility", "hidden");
151                },
152
153                _startLayout: function(){
154                        // summary:
155                        //              startup widgets in view template.
156                        // tags:
157                        //              private
158                        this.app.log("  > in app/ViewBase _startLayout firing layout for name=[",this.name,"], parent.name=[",this.parent.name,"]");
159
160                        if(!this.hasOwnProperty("constraint")){
161                                this.constraint = domAttr.get(this.domNode, "data-app-constraint") || "center";
162                        }
163                        constraints.register(this.constraint);
164
165
166                        this.app.emit("app-initLayout", {
167                                "view": this,
168                                "callback": lang.hitch(this, function(){
169                                                //start widget
170                                                this.startup();
171
172                                                // call view assistant's init() method to initialize view
173                                                this.app.log("  > in app/ViewBase calling init() name=[",this.name,"], parent.name=[",this.parent.name,"]");
174                                                this.init();
175                                                this._started = true;
176                                                if(this._startDef){
177                                                        this._startDef.resolve(this);
178                                                }
179                                })
180                        });
181                },
182
183
184                _loadViewController: function(){
185                        // summary:
186                        //              Load view controller by configuration or by default.
187                        // tags:
188                        //              private
189                        //
190                        var viewControllerDef = new Deferred();
191                        var path;
192
193                        if(!this.controller){ // no longer using this.controller === "none", if we dont have one it means none.
194                                this.app.log("  > in app/ViewBase _loadViewController no controller set for view name=[",this.name,"], parent.name=[",this.parent.name,"]");
195                                viewControllerDef.resolve(true);
196                                return viewControllerDef;
197                        }else{
198                                path = this.controller.replace(/(\.js)$/, "");
199                        }
200
201                        var requireSignal;
202                        try{
203                                var loadFile = path;
204                                var index = loadFile.indexOf("./");
205                                if(index >= 0){
206                                        loadFile = path.substring(index+2);
207                                }
208                                requireSignal = require.on("error", function(error){
209                                        if(viewControllerDef.isResolved() || viewControllerDef.isRejected()){
210                                                return;
211                                        }
212                                        if(error.info[0] && (error.info[0].indexOf(loadFile) >= 0)){
213                                                viewControllerDef.resolve(false);
214                                                requireSignal.remove();
215                                        }
216                                });
217
218                                if(path.indexOf("./") == 0){
219                                        path = "app/"+path;
220                                }
221
222                                require([path], function(controller){
223                                        viewControllerDef.resolve(controller);
224                                        requireSignal.remove();
225                                });
226                        }catch(e){
227                                viewControllerDef.reject(e);
228                                if(requireSignal){
229                                        requireSignal.remove();
230                                }
231                        }
232                        return viewControllerDef;
233                },
234
235                init: function(){
236                        // summary:
237                        //              view life cycle init()
238                },
239
240                beforeActivate: function(){
241                        // summary:
242                        //              view life cycle beforeActivate()
243                },
244
245                afterActivate: function(){
246                        // summary:
247                        //              view life cycle afterActivate()
248                },
249
250                beforeDeactivate: function(){
251                        // summary:
252                        //              view life cycle beforeDeactivate()
253                },
254
255                afterDeactivate: function(){
256                        // summary:
257                        //              view life cycle afterDeactivate()
258                },
259
260                destroy: function(){
261                        // summary:
262                        //              view life cycle destroy()
263                }
264        });
265});
Note: See TracBrowser for help on using the repository browser.