【问题标题】:ember.js displaying list of items, each item with it's own view/controllerember.js 显示项目列表,每个项目都有自己的视图/控制器
【发布时间】:2013-01-30 20:03:30
【问题描述】:

我想要实现的目标: 用视图创建控制器,在这个视图中我有“画廊”对象的列表。每个项目都有自己的视图和控制器。

所有文件都在这里:https://gist.github.com/7e72bb2f532c171b1bf3

它按预期工作,在悬停一些文本后显示/隐藏,但我个人认为这不是很好的解决方案。

我认为我可能应该使用 {{collection}} 帮助器,但是在 ember.js 页面上没有它的文档(代码中有一些,但我不确定这个帮助器是不是一点点过时的,因为在源代码中它说“// TODO:不需要所有这个模块”)。

我尝试使用 itemController 属性,但我仍然在一个文件中有模板。

还尝试在 {{#each}} 中使用 {{render}} 助手,但随后会引发错误。

那么,有没有更好/更清洁的方法来实现我想要的?

编辑

按照 Michael Grassotti 提供的解释完成所有操作后,我有奇怪的行为 - 模板的属性是从 itemController 获取的,但 {{action}} 助手绑定到父控制器。我制作了屏幕截图以显示我正在处理的内容。

itemView 中的“this”基本上指向右控制器(itemController),但目标属性具有父控制器。

在创建{{action "deleteGallery" this target="this"}} 并单击它后,我遇到了屏幕截图中的错误。此刻,我的想法已经不多了……

EDIT2:

好吧,我想多了,itemController 仅用于定义计算属性,而不用于编写 {{action}} 处理程序。

EDIT3: 我认为我的 itemController 和事件目标的问题将得到解决。 https://github.com/emberjs/ember.js/issues/1846

【问题讨论】:

    标签: javascript ember.js


    【解决方案1】:

    我认为我可能应该使用 {{collection}} 帮助器,但是在 ember.js 页面上没有它的文档(代码中有一些,但我不确定这个帮助器是不是一点点过时的,因为在源代码中它说“// TODO:不需要所有这个模块”)。

    同意。收集助手仍然有效,但我不确定它是否会成为公共 API 的一部分。如果可以的话,最好坚持使用 {{#each}} 助手。

    我尝试使用 itemController 属性,但我仍然在一个文件中有模板。

    itemController 属性是一个好的开始。这是为每个项目提供其自己的控制器的最佳方式。

    还尝试在 {{#each}} 中使用 {{render}} 助手,但随后会引发错误。

    是的,{{render}} 助手不是为在 {{each}} 块中使用而设计的。

    那么,有没有更好/更清洁的方法来实现我想要的?

    是的。对于初学者,请使用 itemController 属性。然后给每个它自己的视图,为{{each helper}} 提供一个itemViewClass 选项。例如:

    # in galleries_index.hbs
    {{each controller itemViewClass="App.GalleriesIndexItemView"}
    

    详情请参阅api docs for the each helper 的“无块使用”部分。

    然后自定义App.GalleriesIndexItemView指定模板:

    App.GalleriesIndexItemView = Ember.View.extend({
        templateName: "galleries_index_item",
        tagName: 'li',
        classNames: ['span4'],
        hover: false,
        mouseEnter: function() {
            this.set('hover', true);
        },
        mouseLeave: function() {
            this.set('hover', false);
        }
    });
    

    并将 html 从每个助手移动到模板中:

    # galleries_index_item.hbs
      <div class="thumbnail">
          <a href="#">
              <img src="images/300x200.gif" alt="">
          </a>
          <div class="caption">
              <h4>{{name}}</h4>              
              {{#if view.hover}}
                  <button {{action editGallery this }} class="btn btn-mini" type="button">Edit</button>
                  <button {{action deleteGallery this}} class="btn btn-mini" type="button">Delete</button>
              {{/if}}
          </div>
      </div>
    

    现在每个项目都有自己的视图和控制器。

    【讨论】:

    • 太好了,这正是我想要的,但现在我又一次用头撞墙了。看:gist.github.com/c4e6adb87846737f8e6c - 模板使用来自控制器“omgTest”的属性,但它使用来自父控制器的 deleteGallery?
    • 嗯 - 在上面看到你的编辑。 FWIW 我同意似乎动作助手应该针对您的itemController。我会看看,看看我能找到什么。
    • github.com/emberjs/ember.js/issues/1846 - 我认为这将在下一个版本的 ember 中修复。
    • 谢谢卡米尔 - 没有看到这个问题,但同意看起来正在修复中。
    【解决方案2】:

    我建议您使用Ember.CollectionView。

    您的galleriesIndex 模板如下所示:

    <div class="container">
        <div class="row">
            <div class="span12">
                {{view App.GalleriesListView contentBinding="this"}}
            </div>
        </div>
    </div>
    

    观点:

    App.GalleriesListView = Ember.CollectionView.extend({
        classNameBindings: [':thumbnail', ':thumbnails-list'],
        itemViewClass: Ember.View.extend({
            templateName: "galleriesListItem",
            hover: false,
            mouseEnter: function() { this.set('hover', true); },
            mouseLeave: function() { this.set('hover', false; }
        })
    });
    

    galleriesListItem 模板:

    <li class="span4">
        <div class="thumbnail">
            <a href="#">
                <img src="images/300x200.gif" alt="">
            </a>
            <div class="caption">
                <h4>{{view.content.name}}</h4>                        
                {{#if view.hover}}
                    <button {{action editGallery view.content }} class="btn btn-mini" type="button">Edit</button>
                    <button {{action deleteGallery view.content}} class="btn btn-mini" type="button">Delete</button>
                {{/if}}
            </div>
        </div>
    </li>
    

    我不确定我的代码有没有错误,我只是复制粘贴并写下它的样子。

    关于你看到的TODO,这是因为Ember.CollectionView实际上需要所有ember-handlebars模块,而不仅仅是它需要的文件,你不应该关心这个。

    【讨论】:

    • 感谢您的回答,但 Michael Grassotti 提供了更好的答案 :)(展示了如何为每个项目连接控制器)
    • 我以为您知道这一点,因为您说您确实尝试使用 itemController。无论如何,为@Michael Grassotti +1,我比我更喜欢它的答案!
    猜你喜欢
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多