4

我试图在 Ember 应用程序中很好地实现Foundation Zurb 的 Reveal,但我没有成功。现在有了 pre.4 版本,我再次尝试,结果证明非常简单,但我仍然想知道我是否遵循了正确的模式。如果是这样,我希望这个例子对你的项目有所帮助。

使用:

  • ember-1.0.0-pre.4.js

可以在这个jsfiddle中找到一个工作示例。

我有一个Post对象列表。单击列表项将打开一个模式对话框并显示有关帖子的详细信息。

为了显示列表,我创建了一个 Ember 应用程序并为我的Post模型提供了一个资源:

window.App = Em.Application.create();

App.Post = DS.Model.extend({
    title: DS.attr('string'),
    description: DS.attr('string')
});

App.Post.FIXTURES = [{
    id: 1,
    title: 'Lorem',
    description: 'Lorem ipsum dolor sit amet'
}, {
    id: 2,
    title: 'Ipsum',
    description: 'Fusce ante nulla'
}];

App.Store = DS.Store.extend({
    revision: 11,
    adapter: DS.FixtureAdapter.create()
});

App.Router.map(function () {
    this.resource('posts', {
        path: '/'
    });
});

App.PostsRoute = Em.Route.extend({
    model: function () {
        return App.Post.find();
    }
});

对于模态对话框,我render 'reveal'应用程序模板中包含一个。

<script type="text/x-handlebars">
    {{outlet}}
    {{render "reveal"}}
</script>

我覆盖了(由 Ember 即时生成的)RevealController,因为我需要一个ObjectController并且我创建了一个显示模板。

App.RevealController = Em.ObjectController.extend();

由于我的RevealController的内容是Post模型的一个实例,我可以将它的属性放在模板中:

<script type="text/x-handlebars" data-template-name="reveal">
    <div id="myModal" class="reveal-modal large">
    <h2>{{title}}</h2>
    <p>{{description}}</p>
    <a class="close-reveal-modal">&#215;</a>
    </div>
</script>

当我单击帖子的标题时,我想将 RevealController 的内容设置为帖子的实例。为此,我从帖子openModal模板调用事件并将当前帖子作为其上下文传递:

<script type="text/x-handlebars" data-template-name="posts">
  <ul>
    {{#each controller}}
        <li>
            <a {{action openModal this}} href='#'>{{title}}</a>
        </li>
    {{/each}}
    </ul>
    {{outlet}}
</script>

由于目标冒泡,我可以在ApplicationRoute中定义openModal事件,我可以将RevealController的内容设置为传递的Post并最终显示对话框:

App.ApplicationRoute = Em.Route.extend({
    events: {
        openModal: function (content) {
            this.controllerFor('reveal').set('content', content);
            $('#myModal').reveal();
        }
    }
});

以我目前对 ember 的了解,这感觉是正确的做法,但我很高兴听到是否有任何改进。

4

1 回答 1

1

我认为您的方法绝对没有问题。更多的needs是关于依赖于另一个控制器的控制器,而您似乎在做的只是简单地设置content. Ember.ArrayController您需要稍微更改您的实现以适应在 Ember pre 5 中this.controllerFor@deprecated,但您可以通过以下方式实现:

  • 指定PostsController(我假设其他人)需要RevealControllerusing needs;
  • 将实例传递RevealController给您的openModal事件 ( {{action openModal this controllers.reveal}})。

当然还有其他方法可以实现大致相同的目标。但是,我看到的优点如下:

  • 在事件中使用依赖注入,这对于测试等非常有用……;
  • App.ApplicationRoute没有责任必须找到控制器;

有一个缺点是您将RevealController在少数能够调用 Reveal 的控制器中传递。不过,我并不特别认为这是一个缺点,因为如果您发现自己指定了needs: ['reveal']a lot,那么您始终可以创建一个您ArrayController的 s 扩展的抽象控制器,因为needs它是一个连接属性(参见concatenatedPropertiesEmber's Ember.ControllerMixin):

App.AbstractController = Ember.ArrayController.extend({
    needs: ['reveal']
});

App.PostsController = App.AbstractController.extend({
    // Since needs is a concatenated property, PostsController will have
    // access to 4 controllers: reveal, another, andAnother, andYetAnother.
    needs: ['another', 'andAnother', 'andYetAnother']
});

您对此有何看法?

此外,我能看到的唯一真正使用的非 Ember 代码是:$('#myModal').reveal();. 有没有一种方法可以将 Reveal 代码放入didInsertElementApp.RevealView?然后在那里你可以做类似的事情:this.get('element').reveal();或类似的(也许是子视图?)

于 2013-02-09T20:32:42.273 回答