I desperately need help with an ambitious app I am working on…
The main data model is a dashboard (a user could have multiple dashboards), each dashboard has a number of rows which should be represented by a row view to handle some user input…in addition, each row has number of widgets, since widgets vary wildly when interacting with them they all share the same data model. I made the dashboard to be a CollectionView where it contains row views. so far so good, here comes the tricky part, if I use a CollectionView I will have to override createChildView and try to read the “type” attribute of the model, but it is always null since it is loaded a synchronously via ember-data restful adapter. thus I can’t return the correct class for the widget. I am really stuck here and I really don’t want to switch away from Ember. Feel free to question any of the implied decisions that I made.
Please help me on how to solve this and eventually have widget views nested correctly in row views, which in turn nest correctly the dashboard view.
If you’re still looking for a solution, I made you a jsFiddle showing how to choose a view class at runtime based on the type attribute of a model. This should do the right thing with asynchronously loaded data, too.
Here are the key bits:
<script type="text/x-handlebars" data-template-name="widget">
<h2>{{name}}</h2>
<div class="content">
<!-- This is the magic bit. -->
{{view view.subViewType}}
</div>
</script>
…and:
App.WidgetView = Ember.View.extend({
templateName: "widget",
classNames: ["widget"],
// Choose what kind of view we want to use to render this widget.
// This gets used by our template.
subViewType: function () {
console.log("context:", this.get("context"));
switch (this.get("context.type")) {
case "weather": return App.WeatherView;
case "scores": return App.ScoresView;
default: return App.LoadingView;
}
}.property("context.type"),
// We need to trigger this rerender manually when subViewType
// changes, because Handlebars {{view ...}} isn't smart enough.
subViewTypeDidChange: function () {
this.rerender();
}.observes("subViewType")
});