5

我在玩 ember.js 并且不知怎么地发现如何以正确的方式构建结构。我可以遵循所有示例,但是将它们放在一起时会遇到一些问题。

我正在使用 require.js 和车把。

我的目录结构如下所示:

- app
- - controllers
- - css
- - helpers
- - lib
- - models
- - routes
- - templates
- - - partials
- - views

我的 application.js 看起来像这样:

require.config({
    paths:{
        jquery:'lib/jquery-1.7.2',
        handlebars:'lib/handlebars',
        ember:'lib/ember',
        ember_data:'lib/ember-data',
        text:'lib/requireJS/text',
        md5:'lib/md5',
        spin:'lib/spin'
    },

    shim:{
        'ember':{
            deps:[ 'jquery', 'handlebars'],
            exports:'Ember'
        },
        'ember_data':{
            deps:[ 'ember'],
            exports:'DS'
        }
    },

    waitSeconds:15        
});

define('application'
        ,[
            // Routes
            'routes/app_router'

            // Controller
            ,'controllers/application_controller'

            // Views
            ,'views/application_view'
            ,'views/category/category_list_view'

            // Libraries
            ,'jquery'
            ,'handlebars'
            ,'ember'
            ,'ember_data'
            ,'spin'

        ]
        , function (

             // Router
             Router

             // Controller
            ,ApplicationController

             // Views
            ,ApplicationView
            ,CategoryListView

             // Models
            ,Category
            ,Product
        )
    {
        return  Ember.Application.create({

             VERSION: '1.0.0'

            ,rootElement:'#main'

            // Load Router
            ,Router:Router

            // Load Controllers
            ,ApplicationController:ApplicationController

            // Load associated Views
            ,ApplicationView:ApplicationView
            ,CategoryListView:CategoryListView

            // Load Models
            ,Category:Category
            ,Product:Product

            //Persistence Layer,using default RESTAdapter in ember-data.js.
            ,store:DS.Store.create({
                revision:10
                ,adapter:DS.RESTAdapter.create({
                     bulkCommit:false
                    ,serializer:DS.Serializer.create({
                        primaryKey:function (type) {
                            return type.pk;
                        }
                    })
                    ,mappings:{
                        //categories:Category
                    }
                    ,namespace:'api'
                    ,url: "https://example.org"
                })
            })

            ,ready:function () {

            }
        });
    }
);

然后我的应用程序控制器

define(
    'controllers/application_controller'
    ,['ember' ],
    function () {
        return Ember.Controller.extend({
            init: function() {
            }
        });
    }
);

应用视图:

define('views/application_view', [
        'text!templates/application.html',
        'ember'
    ],
    function(Application_markup) {
        return Ember.View.extend({
            template: Ember.Handlebars.compile( Application_markup ),
            elementId: 'container',
            didInsertElement: function() {
                this.$().hide().show("slow");
            }
        });
    }
);

最后,application.html 模板

<div id="container">

    <div id="header">
        FOO BAR
    </div>

    <div id="navigation">
        {{outlet mainNavigation}}
    </div>

    <div id="content">

    </div>

    <div id="footer">

    </div>

</div>

我现在要做的是在主应用程序模板(category_list)中包含另一个模板。我想我要么必须在 HTML 模板本身中执行此操作,要么在应用程序视图中执行此操作 - 但在后一种情况下,我不知道如何配置/解析/绑定多个模板。

构建单独的、独立的、模块化的模板并将它们放在一起的最佳实践是什么?这究竟应该发生在哪里?或者这甚至是使用 ember.js 的错误方法?

也许你们中的一个人可以让我更清楚一些事情。谢谢。

编辑#1

app_router.js

define('routes/app_router',
    ['ember' ],
    function () {
        return  Em.Router.extend({
            enableLogging:true, //useful for development
            /*  location property:  'hash': Uses URL fragment identifiers (like #/blog/1) for routing.
             'history': Uses the browser's history.pushstate API for routing. Only works in modern browsers with pushstate support.
             'none': Does not read or set the browser URL, but still allows for routing to happen. Useful for testing.*/
            location:'hash',
            /*   location: 'history',
             rootURL:'/app',*/
            root:Ember.Route.extend({
                index:Ember.Route.extend({
                    route:'/'

                    /*,connectOutlets:function (router) {
                        //Render application View ,sign in.
                        v = router.get('applicationController').get('view');
                        if (v) v.remove();
                        App.router.get('applicationController').set('loggedin', false);

                        router.get('applicationController').connectOutlet({name:'login', outletName:'loginform'});
                        router.get('loginController').enterLogin();

                    }*/
                })
                /*,contacts:Em.Route.extend({
                    route:'/contacts',

                    showContact:function (router, event) {
                        router.transitionTo('contacts.contact.index', event.context);
                    },

                    showNewContact:function (router) {
                        router.transitionTo('contacts.newContact', {});
                    },
                    logout:function (router) {

                        jQuery.ajax({
                            url:'/site/logout',
                            type:'POST',
                            success:function (response) {
                                if (!response.authenticated) {
                                    router.get('applicationController').set('loggedin', false).get('view').remove();
                                    router.transitionTo('root.index', {});
                                }
                            }
                        })
                    },


                    index:Em.Route.extend({
                        route:'/',
                        connectOutlets:function (router) {
                            if (router.get('applicationController').get('loggedin'))
                                router.get('applicationController').connectOutlet('contacts', App.store.findAll(App.Contact));
                            else   router.transitionTo('root.index');
                        }
                    }),

                    contact:Em.Route.extend({
                        route:'/contact',
                        index:Em.Route.extend({
                            route:'/:contact_id',
                            deserialize:function (router, urlParams) {
                                return App.store.find(App.Contact, urlParams.contact_id);
                                debugger;
                            },

                            showEdit:function (router) {
                                router.transitionTo('contacts.contact.edit');
                            },

                            connectOutlets:function (router, context) {
                                if (router.get('applicationController').get('loggedin'))
                                    router.get('contactsController').connectOutlet('contact', context);
                                else   router.transitionTo('root.index');
                            }
                        }),

                        edit:Em.Route.extend({
                            route:'edit',

                            cancelEdit:function (router) {
                                router.transitionTo('contacts.contact.index');
                            },

                            connectOutlets:function (router) {
                                if (router.get('applicationController').get('loggedin')) {
                                    var contactsController = router.get('contactsController');
                                    contactsController.connectOutlet('editContact', router.get('contactController').get('content'));
                                    router.get('editContactController').enterEditing();
                                } else     router.transitionTo('root.index');
                            },

                            exit:function (router) {
                                router.get('editContactController').exitEditing();
                            }
                        })
                    }),
                    newContact:Em.Route.extend({
                        route:'/contacts/new',

                        cancelEdit:function (router) {
                            router.transitionTo('contacts.index');
                        },

                        connectOutlets:function (router) {
                            if (router.get('applicationController').get('loggedin')) {
                                router.get('contactsController').connectOutlet('editContact', {});
                                router.get('editContactController').enterEditing();
                            } else     router.transitionTo('root.index');
                        },

                        exit:function (router) {
                            router.get('editContactController').exitEditing();
                        }
                    })
                })*/
            })
        });
    }
);

编辑#2

我现在按如下方式更改了路由器,但它没有做任何事情。

define('routes/apps_router', ['ember'],
    function () {
        return Em.Router.extend({
            enableLogging:true
            ,location:'hash'

         ,map: function (match) {
            match("/").to("CategoryList", function (match) {
                match("/").to("mainNavigation");
            });
        }

        ,root:Ember.Route.extend({
            index:Ember.Route.extend({
                route:'/'

                ,renderTemplates: function() {
                    this.render('mainNavigation', {
                        into: 'CategoryList'
                    });
                }
           // ....
        });
    }
);

亲切的问候,克里斯托弗

4

1 回答 1

4

如果您将最新版本的 ember 与 v2 路由器一起使用,您可以执行以下操作:

App.Router.map(function (match) {
    match("/").to("categoryList", function (match) {
        match("/").to("foo");
    });
});

在您的 CatergoryList 模板中,放置一个 {{outlet}}(您可以选择命名它)

然后,您要插入到categoryList 的模板的路径将如下所示:

App.fooRouter = Ember.Router.extend({
renderTemplates:function () {
        this.render('foo', {
            into:'catergoryList'
        });
    }
})

在实践中可以找到一个很好的例子: https ://github.com/sh4n3d4v15/ember-todos

于 2013-01-07T10:04:55.410 回答