Ember.JS - 如何在同一页面中使用多个模型、控制器和视图? [英] Ember.JS - How to use multiple models, controllers and views in same page?

查看:22
本文介绍了Ember.JS - 如何在同一页面中使用多个模型、控制器和视图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我主要了解 Ember.JS 的基础知识.大多数示例实际上只是处理单个控制器和模型以在页面上显示某些内容.我真的很想用 Ember 构建一个完整的网络应用程序,所以谁能告诉我如何组织和连接多个控制器、模型和视图到一个页面中?

例如,如果我导航到/app/posts,我想显示一个导航栏,里面有很多东西,包括一些登录信息,一个侧边栏,用来搜索附加的控制器,一堆帖子中间,可能还有一个 Twitter 提要填充在侧边栏上,其中包含一个 TwitterFeedController.

我如何将一堆这些连接在一起.在 Ember.JS 中使用自己的控制器、模型和视图实现Sections"的基本方法是什么?

我知道有名为outlets"的地方.当前文档似乎没有提到它过去在应用程序模板中有一个主要的 {{ outllet }} .我也无法在他们的公共 API 文档中找到定义(可能是盲目的......).

提前致谢!

解决方案

希望这能回答 Example1 和这个也是 Example2

<script type="text/x-handlebars" data-template-name="_navbar"><div class="navbar navbar-inverse"><div class="navbar-inner">{{#linkTo "app" class="brand"}}{{unbound App.app_title}}{{/linkTo}}<ul class="nav"><li class="divider-vertical">{{#linkTo "app"}}首页{{/linkTo}}<li class="divider-vertical">{{#linkTo "products"}}产品{{/linkTo}}

<script type="text/x-handlebars" data-template-name="_footer"><div class="row"><div class="span12">&复制;2013:1.0-pre4 - {{unbound App.contact}}

<script type="text/x-handlebars" data-template-name="app"><h2>家</h2><p>培根 ipsum dolor 坐 amet 里脊短肋短里脊肉丸香肠鸡肉熏牛肉.汉堡香肠三尖,培根排骨 bresaola 短排骨查克法兰克福肩.Fatback 五花肉 turducken, 火腿鼓槌意大利腊肠汉堡猪肉香肠.乔尔咸牛肉安多维尔小腿布丁.Shankle 意大利腊肠咸牛肉,熏牛肉 leberkas turducken 鹿肉肩肥背下颌球尖磨圆的干酪和多维尔布丁.</p><p>Biltong boudin 火鸡臀部柄球尖,剥去牛排鼓槌排骨.牛短肋 leberkas 猪沙朗小腿小腿臀部汉堡汉堡法兰克福火腿飞节.Bresaola 火鸡培根火腿意大利腊肠意大利培根培根肉饼磨圆球尖菲力牛排牛排 kielbasa 舌头夹头条牛排.T-bone leberkas 牛肋骨 kielbasa shankle 猪排排骨夹头条牛排肩法兰克福火鸡.猪里脊火腿牛鸡肉布丁鹿肉.菲力牛排牛颈猪球尖,肉丸布丁 leberkas 火腿短里脊鼓槌里脊鹿肉鸡.Chuck 牛肉菲力牛排意大利面、肥后侧翼火腿、咸牛肉肉饼短排骨培根.</p><script type="text/x-handlebars" data-template-name="categories"><h2>类别</h2><p>列出可用的产品和服务</p><ul class="缩略图">{{#控制器中的每个类别}}

  • <div class="缩略图"><h4>{{category.name}}</h4><img {{bindAttr src="category.imageUrl" alt="category.name"}}/>{{#linkTo "products.category" category class="btn"}}细节{{/链接到}}
  • {{别的}}<li>正在加载...</li>{{/每个}}<小时/><script type="text/x-handlebars" data-template-name="products">{{渲染类别}}{{出口}}<script type="text/x-handlebars" data-template-name="products/index"><h2>产品</h2><ul class="缩略图">{{#控制器中的每个产品}}

  • <div class="缩略图"><h4>{{product.name}}</h4><img {{bindAttr src="product.imageUrl" alt="product.name"}}/>{{#linkTo "products.product" product class="btn"}}细节{{/链接到}}
  • {{别的}}<li>正在加载...</li>{{/每个}}<script type="text/x-handlebars" data-template-name="products/product"><h4><em style="color: gray">产品</em>/<em style="color: gray">类别:{{category.name}}</em>/{{名称}}</h4><br/><img {{bindAttr src="imageUrl" alt="name"}}/>$ {{价格}} 哈哈哈哈<script type="text/x-handlebars" data-template-name="products/category"><h2>{{name}}</h2><script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.min.js"></script><script type="text/javascript" src="https://raw.github.com/wycats/handlebars.js/1.0.rc.2/dist/handlebars.js"></script><script type="text/javascript" src="https://raw.github.com/emberjs/ember.js/release-builds/ember-1.0.0-pre.4.js"></脚本><script type="text/javascript" src="https://raw.github.com/MilkyWayJoe/ember.js/master/ember.min.js"></script>var BaseApp = Em.Application.extend({app_title: '汽车网店',联系:函数(){if(this.get('link') !=='') {var html = '<a href="%@" target="_blank">%@</a>'.fmt(this.get('link'), this.get('author'));返回新的 Handlebars.SafeString(html);} 别的 {返回 this.get('作者');}}.property('作者', '链接')});//扩展 - 结束window.App = BaseApp.create({作者:'你的名字在这里',链接:'https://twitter.com/torontoemberjs'});//控制器 - 开始App.ShopController = Em.ArrayController.extend();App.ProductsController = Em.ArrayController.extend();App.ProductsIndexController = Em.ArrayController.extend();App.CategoriesController = Em.ArrayController.extend();//控制器 - 结束//路线 - 开始App.Router.map(function() {this.resource('app');this.resource('产品', function() {this.route('product', {path: 'product/:product_id'});this.route('category', {path: 'category/:category_id'})});});App.ApplicationRoute = Em.Route.extend({设置控制器:函数(){this.controllerFor('categories').set('model', App.Category.find());}});App.ProductsIndexRoute = Em.Route.extend({模型:函数(){返回 App.Product.find();}});App.IndexRoute = Em.Route.extend({重定向:函数(){this.transitionTo('app');}});//路线 - 结束//模型 - 开始//从 DS 命名空间为应用程序定义数据存储App.Store = DS.Store.extend({//直到 Ember 达到 1.0,Ember-Data 将使用修订版//提醒开发人员有关 API 的重大更改.当时我在//写这篇文章,Ember-Data 正在修订 11.要了解更多信息,请访问://https://github.com/emberjs/data/blob/master/BREAKING_CHANGES.md修订:11,//定义你的适配器.适配器负责翻译"来自//将后端 API 转换为 Ember-Data 使其工作所需的内容.余烬数据//自带一个 REST Adapter 和一个 Fixture Adapter,后者对于//调试和模拟应用程序.此示例使用 Fixture Adapter适配器:'DS.FixtureAdapter'});App.Category = DS.Model.extend({名称:DS.attr('string'),imageUrl: DS.attr('string'),产品:DS.hasMany('App.Product')});App.Product = DS.Model.extend({名称:DS.attr('string'),imageUrl: DS.attr('string'),价格:DS.attr('number'),类别:DS.belongsTo('App.Category')});//加载样本数据//请注意,所有装置都有一个 `id` 属性.那是因为 Ember-Data 需要你的//模型有一个 Id,但你没有在你的模型类上定义它.App.Category.FIXTURES = [{编号:1,名称:'空调',imageUrl: 'http://img9.imageshack.us/img9/1207/howtoreplaceyourcarairc.jpg',产品: []},{编号:2,name: '轮胎',imageUrl: 'http://img526.imageshack.us/img526/5290/r8wheel1ljpg0f089f10250.jpg',产品: []},{编号:3,name: '刹车',imageUrl: 'http://img651.imageshack.us/img651/5600/brakes.gif',产品: []},{编号:4,name: '排气',imageUrl: 'http://img217.imageshack.us/img217/7366/carbon20fiber20exhaust2.jpg',产品: []},{编号:5,name: '电池',imageUrl: 'http://img842.imageshack.us/img842/268/t2ec16nhjhqe9nzej50bqu7.jpg',产品: []},{编号:6,name: '雨刷',imageUrl: 'http://img145.imageshack.us/img145/3750/1208764x64.jpg',产品: []},{编号:7,名称:'GPS',imageUrl: 'http://img687.imageshack.us/img687/8899/kgrhqroifcpor3cm0bq1ufc.jpg',产品:[701,702,703]},{编号:8,name: '挡风玻璃',imageUrl: 'http://img405.imageshack.us/img405/6826/windshield3thumb.jpg',产品: []}];App.Product.FIXTURES = [{编号:201,名称:'倍耐力 P4 四季',类别:2,价格:9999,imageUrl: 'http://img4.imageshack.us/img4/4372/pirellip4fourseasonslg.jpg'},{编号:701,名称:'Tomtom Start 4.3" GPS (45TM)',类别:7,价格:12999,imageUrl: 'http://img856.imageshack.us/img856/7471/seeq2501.jpg'},{编号:702,名称:'Garmin nüvi 4.3" GPS (40)',类别:7,价格:11999,imageUrl: 'http://img27.imageshack.us/img27/5116/88121963.jpg'},{编号:703,名称:'Magellan RoadMate 2230T 4.3" GPS',类别:7,价格:14399,imageUrl: 'http://img820.imageshack.us/img820/7981/36361380.png'}];//模型 - 结束//视图 - 开始//视图 - 结束

    I mostly understand the basics of Ember.JS. Most examples out there really just deal with a single controller and a model to show something on a page. I am really after building a full web app with Ember so can anyone tell me how do I organize and connect multiple controllers, models and views into a single page?

    For example, if I navigate to /app/posts, I want to show a navigation-bar with bunch of things including some logged in information, a sidebar to search with a controller attached to it, a bunch of posts listed in the middle and maybe a twitter feed populated on the sidebar with a TwitterFeedController.

    How do I connect a bunch of these together. What is the basic way to achieve "Sections" with their own controllers and models and views in Ember.JS?

    I understand there's named "outlets". Current documentation doesn't seem to mention it past having a main {{ outllet }} in application template. I can't find the definition on their public API docs too (might be blind...).

    Thanks in advance!

    解决方案

    Hope this answers Example1 and this one too Example2

    <script type="text/x-handlebars" data-template-name="application">
        {{partial 'navbar'}}
        {{outlet}}   
        {{partial 'footer'}}
    </script>
    
    <script type="text/x-handlebars" data-template-name="_navbar">
        <div class="navbar navbar-inverse">
            <div class="navbar-inner">
                {{#linkTo "app" class="brand"}}{{unbound App.app_title}}{{/linkTo}}
                <ul class="nav">
                    <li class="divider-vertical">
                        {{#linkTo "app"}}Home{{/linkTo}}
                    </li>
                    <li class="divider-vertical">
                        {{#linkTo "products"}}Products{{/linkTo}}
                    </li>
                </ul>
            </div>
        </div>
    </script>
    
    <script type="text/x-handlebars" data-template-name="_footer">
        <div class="row">
            <div class="span12">
                &copy; 2013:1.0-pre4 - {{unbound App.contact}} 
            </div>
        </div>    
    </script>
    
    <script type="text/x-handlebars" data-template-name="app">
        <h2>Home</h2>
        <p>Bacon ipsum dolor sit amet tenderloin short ribs short loin meatball sausage chicken pastrami. Hamburger sausage tri-tip, bacon spare ribs bresaola short ribs chuck frankfurter shoulder. Fatback pork belly turducken, ham drumstick salami hamburger pork sausage. Jowl corned beef andouille shank boudin. Shankle salami corned beef, pastrami leberkas turducken venison shoulder fatback jowl ball tip ground round biltong andouille boudin.</p>
        <p>Biltong boudin turkey rump shankle ball tip, strip steak drumstick spare ribs. Cow short ribs leberkas swine sirloin shank drumstick rump hamburger frankfurter ham hock. Bresaola turkey bacon prosciutto salami jowl pancetta meatloaf ground round ball tip filet mignon kielbasa tongue chuck strip steak. T-bone leberkas beef ribs kielbasa shankle pork chop spare ribs chuck strip steak shoulder frankfurter turducken. Pork loin ham cow chicken boudin venison. Filet mignon cow jowl pig ball tip, meatball boudin leberkas ham short loin drumstick tenderloin venison chicken. Chuck beef filet mignon capicola shankle, fatback flank ham hock corned beef meatloaf short ribs bacon.</p>
    </script>
    
    <script type="text/x-handlebars" data-template-name="categories">
        <h2>Categories</h2>
        <p>Listing available products and services</p>
        <ul class="thumbnails">
        {{#each category in controller}}
            <li class="span3">
                <div class="thumbnail">
                    <h4>{{category.name}}</h4>
                    <img {{bindAttr src="category.imageUrl" alt="category.name"}} />
                    {{#linkTo "products.category" category class="btn"}}
                        Details
                    {{/linkTo}}
                </div>
            </li>
        {{else}}
            <li>Loading...</li>
        {{/each}}
        </ul>
        <hr />
    </script>
    
    <script type="text/x-handlebars" data-template-name="products">
        {{render categories}}
        {{outlet}}
    </script>
    
    <script type="text/x-handlebars" data-template-name="products/index">
        <h2>Products</h2>
        <ul class="thumbnails">
        {{#each product in controller}}
            <li class="span3">
                <div class="thumbnail">
                    <h4>{{product.name}}</h4>
                    <img {{bindAttr src="product.imageUrl" alt="product.name"}} />
                    {{#linkTo "products.product" product class="btn"}}
                        Details
                    {{/linkTo}}
                </div>
            </li>
        {{else}}
            <li>Loading...</li>
        {{/each}}
        </ul>
    </script>
    
    <script type="text/x-handlebars" data-template-name="products/product">
        <h4><em style="color: gray">Products</em>/<em style="color: gray">Category: {{category.name}}</em>/{{name}}</h4><br />
        <img {{bindAttr src="imageUrl" alt="name"}}/>
        $ {{price}} hahahahaha
    </script>
    
    <script type="text/x-handlebars" data-template-name="products/category">
        <h2>{{name}}</h2>
    </script>
    
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
    <script type="text/javascript" src="https://raw.github.com/wycats/handlebars.js/1.0.rc.2/dist/handlebars.js"></script>
    <script type="text/javascript" src="https://raw.github.com/emberjs/ember.js/release-builds/ember-1.0.0-pre.4.js"></script>
    <script type="text/javascript" src="https://raw.github.com/MilkyWayJoe/ember.js/master/ember.min.js"></script>
    
    
    var BaseApp = Em.Application.extend({
        app_title: 'Auto Web Shop',
        contact: function() {
            if(this.get('link') !== '') {
                var html = '<a href="%@" target="_blank">%@</a>'
                           .fmt(this.get('link'), this.get('author'));
                return new Handlebars.SafeString(html);
            } else {
                return this.get('author');
            }
        }.property('author', 'link') 
    });
    
    // Extensions - End
    
    window.App = BaseApp.create({
        author: 'Your Name Here',
        link: 'https://twitter.com/torontoemberjs'
    });
    
    // Controllers - Begin
    
    App.ShopController = Em.ArrayController.extend();
    App.ProductsController = Em.ArrayController.extend();
    App.ProductsIndexController = Em.ArrayController.extend();
    App.CategoriesController = Em.ArrayController.extend();
    
    // Controllers - End
    
    // Routes - Begin
    
    App.Router.map(function() {
        this.resource('app');
        this.resource('products', function() {
            this.route('product', {path: 'product/:product_id'});
            this.route('category', {path: 'category/:category_id'})
        });
    });
    
    App.ApplicationRoute = Em.Route.extend({
      setupController: function() {
          this.controllerFor('categories').set('model', App.Category.find());
      }
    });
    
    App.ProductsIndexRoute = Em.Route.extend({
        model: function() {
            return App.Product.find();
        }
    });
    
    App.IndexRoute = Em.Route.extend({
        redirect: function() {
            this.transitionTo('app');   
        }
    });
    
    // Routes - End
    
    // Models - Begin
    
    // Defining a Data Store for the application from DS namespace
    App.Store = DS.Store.extend({
        // Until Ember reaches 1.0, Ember-Data will use a revisions to 
        // alert developers about breaking changes to the API. At the time I'm 
        // writing this, Ember-Data is on revision 11. To find out more, go to:
        // https://github.com/emberjs/data/blob/master/BREAKING_CHANGES.md
        revision: 11,
        // Define your adapter. The Adapter is responsible to 'translate' the data from
        // your backend API into what Ember-Data needs in order for it to work. Ember-Data
        // comes with a REST Adapter and a Fixture Adapter, the later is very useful for 
        // debugging and for mocking up an application. This example uses the Fixture Adapter
        adapter: 'DS.FixtureAdapter'
    });
    
    App.Category = DS.Model.extend({
        name: DS.attr('string'),    
        imageUrl: DS.attr('string'),
        products: DS.hasMany('App.Product')
    });
    
    App.Product = DS.Model.extend({
        name: DS.attr('string'),
        imageUrl: DS.attr('string'),
        price: DS.attr('number'),
        category: DS.belongsTo('App.Category')
    });
    
    // Loading sample data
    // Note that all fixtures have an `id` property. That's because Ember-Data needs your 
    // models to have an Id, but you don't define it on your model classes.
    App.Category.FIXTURES = [
        {
            id: 1, 
            name: 'Air Conditioners', 
            imageUrl: 'http://img9.imageshack.us/img9/1207/howtoreplaceyourcarairc.jpg', 
            products: []
        },
        {    
            id: 2,
            name: 'Tires', 
            imageUrl: 'http://img526.imageshack.us/img526/5290/r8wheel1ljpg0f089f10250.jpg', 
            products: []
        },
        {
            id: 3, 
            name: 'Brakes', 
            imageUrl: 'http://img651.imageshack.us/img651/5600/brakes.gif', 
            products: []
        },
        {
            id: 4,
            name: 'Exhausts', 
            imageUrl: 'http://img217.imageshack.us/img217/7366/carbon20fibre20exhaust2.jpg', 
            products: []
        },
        {
            id: 5, 
            name: 'Batteries', 
            imageUrl: 'http://img842.imageshack.us/img842/268/t2ec16nhjhqe9nzej50bqu7.jpg', 
            products: []
        },
        {
            id: 6,
            name: 'Wipers', 
            imageUrl: 'http://img145.imageshack.us/img145/3750/1208764x64.jpg', 
            products: []
        },
        {
            id: 7, 
            name: 'GPS', 
            imageUrl: 'http://img687.imageshack.us/img687/8899/kgrhqroifcpor3cm0bq1ufc.jpg',
            products: [701,702,703]
        }, 
        {
            id: 8,
            name: 'Windshields',
            imageUrl: 'http://img405.imageshack.us/img405/6826/windshield3thumb.jpg',
            products: []
        }
    ];
    
    App.Product.FIXTURES = [
        {
            id: 201,
            name: 'Pirelli P4 Four Seasons',
            category: 2,
            price: 9999,
            imageUrl: 'http://img4.imageshack.us/img4/4372/pirellip4fourseasonslg.jpg'
        },
        {
            id: 701, 
            name: 'Tomtom Start 4.3" GPS (45TM)', 
            category: 7, 
            price: 12999, 
            imageUrl: 'http://img856.imageshack.us/img856/7471/seeq2501.jpg'
        },
        {
            id: 702, 
            name: 'Garmin nüvi 4.3" GPS (40)', 
            category: 7,
            price: 11999, 
            imageUrl: 'http://img27.imageshack.us/img27/5116/88121963.jpg'
        },
        {
            id: 703, 
            name: 'Magellan RoadMate 2230T 4.3" GPS ', 
            category: 7, 
            price: 14399, 
            imageUrl: 'http://img820.imageshack.us/img820/7981/36361380.png'
        }
    ];
    
    // Models - End
    
    
    
    // Views - Begin
    
    // Views - End
    

    这篇关于Ember.JS - 如何在同一页面中使用多个模型、控制器和视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    前端开发最新文章
    热门教程
    热门工具
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆