2
votes

Update : 6 Jan 13

Goal :

I have a main view which I am using as a scaffolding. I intend to insert child views in different sections of the main view . Main view is dynamic and may be replaced with another view when user selects a different route.

Approach #1:

I defined an outlet for main view, and named outlets for each child view in the main view. Outlets work fine for top level template (main-view), however, the nested child outlets are not being rendered. Does API support nested outlets?

Approach #2 : In child template , I tried {{#with }} to define the scope so that a right controller is selected and child view is rendered with the correct data. However, {{#with }} does not seem to be working as expected .

I would have liked to put up jsfiddle , but they have an older version of Ember.js

########ROUTER Config ########

    App.Router.map(function (match) {
        match('').to('index');
        match('/').to('index');
        match('/models').to('models');
        match('/list').to('list');
    });

    App.IndexRoute = Ember.Route.extend({
        redirect : function () {
            this.transitionTo('models');
        }
    });

    App.ModelsRoute = Ember.Route.extend({
        renderTemplates : function () {
            var navigationController = this.controllerFor('navigation'),
                fuseColController = this.controllerFor('fuseCol');
            this.render('navigation-view', {
                outlet : 'navigationContent',
                controller : navigationController
            });
            this.render({ outlet : 'mainContent' });
   /* this does not work , is it due to nested outlets not being supported? 
    Are there any events fired when render on mainContent is complete so that child views may be rendered?
this.render('col-view', {outlet : 'fuseColContainer', controller: fuseController}); */
            console.log("On Models Route Render");
        },
        connectOutlets : function (router, context) {
            console.log("On Models connnectOutlets");//Is Never called 
        },
        connectOutlet : function (router, context) {
            console.log("On Models connnectOutlet"); //Is Never called 
        },
        setupControllers : function (controller) {
            console.log("Models setupControllers called");
//            this.controllerFor('fuseCol').connectOutlet('fuseColContainer', 'fuseCol');
//deprecated in the new API ?? connecteOutlet throws up error !!! 
        }

    });


############################# Templates #######################

<script type="text/x-handlebars">
    <div class="container-fluid">
        {{outlet navigationContent}}//This  WORKS !!!

        {{outlet mainContent}}// This WORKS !!!
    </div>
</script>


<script type="text/x-handlebars" id="models-view">
    <div class="container-fluid">
        <div class="row-fluid">
            <div class="span2">
                    Nested Child 1 
                    {{outlet fuseColContainer}}  //Does Not Work  
            </div>
            <div class="span10">
                <div class="row-fluid">
                    <div class="row-fluid">
                        <div class="span10">Nested Child 2</div>
                        <div class="span2">Nested Child 3</div>
                    </div>
                    <div class="row-fluid">Nest Child 4</div>
                </div>
            </div>
        </div>
    </div>
</script>

<script type="text/x-handlebars" data-template-name="fuse-col-view" id="fuse-col-view">
    <select multiple="true" id="fuseColList">
        {{#each item in  controller}}
        <option>{{item.name}}</option>
        {{/each}}
    </select>
</script>
################### Controller #################

  App.Router = Ember.Router.extend();

    App.Router.map(function (match) {
        match('').to('index');
        match('/').to('index');
        match('/models').to('models');
        match('/list').to('list');
    });

    App.IndexRoute = Ember.Route.extend({
        redirect : function () {
            this.transitionTo('models');
        }
    });

    App.ModelsRoute = Ember.Route.extend({
        renderTemplates : function () {
            var navigationController = this.controllerFor('navigation'),
                fuseColController = this.controllerFor('fuseCol');
            this.render('navigation-view', {
                outlet : 'navigationContent',
                controller : navigationController
            });
            this.render({ outlet : 'mainContent' });
            /* This does not work , i think there should be a better approach
            this.render('fuse-col-view', {outlet : 'fuseColContainer', controller : fuseColController});*/
            console.log("Models render called");
        },
        connectOutlets : function (router, context) {
            console.log("Models connnectOutlets called");
        },
        connectOutlet : function (router, context) {
            console.log("Models connnectOutlet called");
        },
        setupControllers : function (controller, playlist) {
            console.log("Models setupControllers called");
    /*there is no connectOutlet method on controller in API ??*/
//            this.controllerFor('fuseCol').connectOutlet('fuseColcontainer', 'fuseCol');
        }

    });



    App.FuseColController = Ember.ArrayController.extend({
        content : [],
        init : function () {
            this.pushObject(App.FuseColItem.create({name : 'Col 1'}));
            this.pushObject(App.FuseColItem.create({name : 'Col 2'}));
            this.pushObject(App.FuseColItem.create({name : 'Col 3'}));
        }
    });

    App.FuseColItem = Ember.Object.extend({
        name : 'Sample Col'
    });

    App.FuseColView = Ember.View.extend({
        templateName : 'fuse-col-view'
    });

Ember.js version : Build on 3rd Jan 13

I have omitted other bits of the code to keep it brief.Please Add a comment for more info.

1

1 Answers

0
votes

have you set up a router? If so, this wil automatically create the corresponding namespaced view, controller for the route name. As you have rightly done, if you need an ArrayController you would instantiate this manually.

If you set up the router like this:

App.Router.map(function (match) {
    match("/").to("col");
});

App.colRoute = Ember.Route.extend({
    renderTemplate: function(){
        this.render('col-view')
    }
})

then Ember will link colView,colController (your defined arrayController) and your 'col-view' template through the router name.

I don't think you will need to use "#with" and I think I've read somewhere that it is bad practice...I think ;)