7

以前、コントローラーにあるコレクションをリストシナリオビューにバインドしたいという質問をしましたが、詳細を追加し、テンプレートとビューを構造に編集して、いくつかの追加のサブルートを作成しました。

root.contacts.details -> /contacts/:contact_id
root.contacts.edit -> /contacts/:contact_id/edit

私のシナリオでは、私は最初に次detailsのように呼び出し始めましたconnectOutlets

[...]
connectOutlets: function (router, contact) {
    router.get('contactController').set('contact', contact);
    router.get('applicationController').connectOutlet('contacts');
},[...]

これにより、ブラウザのナビゲーションバーのルートが変更されますが、同じビューが読み込まれるため、連絡先ではなく連絡を次のように変更.connectOutletしました

[...]
connectOutlets: function (router, contact) {
    router.get('contactController').set('contact', contact);
    router.get('applicationController').connectOutlet('contact');
},[...]

このため、Emberがという名前のコントローラーを見つけることができなかったため、新しいコントローラーを作成する必要がありました。そのため、aとaでcontactController終わり、MVCパターンを壊して、追加のクラスを作成していると思います。同期で発生する可能性のある問題を維持します(連絡先を編集するときは、のコレクションと手動で同期する必要があります)。また、に移動すると、で同じ名前を使用しているため、詳細ビューが読み込まれます。だから私がしていることは正しくありえない。シナリオごとにコントローラーを作成したくありません。私はこれがそれが行われる方法ではないと確信しています。contactControllercontactsControllercontactsController/#/contacts/2/edit.connectOutlet('contact')

App.EditContactViewまた、リソース名の代わりにビュー(私の場合)を設定しようとしましたが、「名前またはviewClassは渡すことができますが、両方は渡すことができませんconnectOutlets」というエラーが発生しましたが、パススルーではなく、引数として。viewClassconnectOutlet

また、ビューまたはビューのインスタンスをルート自体に設定しようとしましたが、JavaScriptが壊れるか、場合によっては「App.EditContactViewにメソッドCharAtがありません」というエラーが表示されます。

それからまた、私は少し迷子になりました。SOやその他の場所で他の質問を見たことがありますが、私が見つけた質問は、ember-routermanagerGordon Hemptonによって使用されているか(これは良さそうですが、今だけビルトインを使用することに興味があります)、Ember.StateManagerまたはすべて。ドキュメントはまだこれらのことについてあまり説明していません。

質問:すべてのCRUDシナリオに対処するための理想的なアプローチは何でしょうEmber.Routerか?contactsControllerすべてを一覧表示し、1つを検索し、1つを編集し、1つを追加し、1つの連絡先を削除できるようにしたいと思います。現在、名前の問題のため、1つと1つ、、、contactsControllerがあります。findAllcontactControllerfindeditremoveadd

私は現在ember-dataを使用していないので、ember-dataを参照しない例にもっと興味があります(今のところプラグインなしで赤ちゃんのステップを実行しています)。

これが私のルーターの現在のバージョンです:

JS

App.Router = Ember.Router.extend({
    enableLogging: true,
    location: 'hash',

    root: Ember.Route.extend({
        // EVENTS
        gotoHome: Ember.Route.transitionTo('home'),
        gotoContacts: Ember.Route.transitionTo('contacts.index'),

        // STATES
        home: Ember.Route.extend({
            route: '/',
            connectOutlets: function (router, context) {
                router.get('applicationController').connectOutlet('home');
            }
        }),
        contacts: Ember.Route.extend({
            route: '/contacts',
            index: Ember.Route.extend({
                route: '/',
                contactDetails: function (router, context) {
                    var contact = context.context;
                    router.transitionTo('details', contact);
                },
                contactEdit: function (router, context) {
                    var contact = context.context;
                    router.transitionTo('edit', contact);
                },
                connectOutlets: function (router, context) {
                    router.get('contactsController').findAll();
                    router.get('applicationController').connectOutlet('contacts', router.get('contactsController').content);
                }
            }),
            details: Ember.Route.extend({
                route: '/:contact_id',
                view: App.ContactView,
                connectOutlets: function (router, contact) {
                    router.get('contactController').set('contact', contact);
                    router.get('applicationController').connectOutlet('contact');
                },
                serialize: function (router, contact) {
                    return { "contact_id": contact.get('id') }
                },
                deserialize: function (router, params) {
                    return router.get('contactController').find(params["contact_id"]);
                }
            }),
            edit: Ember.Route.extend({
                route: '/:contact_id/edit',
                viewClass: App.EditContactView,
                connectOutlets: function (router, contact) {
                    router.get('contactController').set('contact', contact);
                    router.get('applicationController').connectOutlet('contact');
                },
                serialize: function (router, contact) {
                    return { "contact_id": contact.get('id') }
                },
                deserialize: function (router, params) {
                    return router.get('contactController').find(params["contact_id"]);
                }
            })
        })
    })
});
App.initialize();

関連するテンプレート

<script type="text/x-handlebars" data-template-name="contact-details">
    {{#if controller.isLoaded}} 
        <img {{bindAttr src="contact.imageUrl" alt="contact.fullName" title="contact.fullName"}} width="210" height="240" /><br />
        <strong>{{contact.fullName}}</strong><br />
        <strong>{{contact.alias}}</strong>
    {{else}}
        <img src="images/l.gif" alt="" /> Loading...
    {{/if}}
</script>

<script type="text/x-handlebars" data-template-name="contact-edit">
    <strong>Edit contact</strong><br />
    First Name: <input type="text" id="txtFirstName" {{bindAttr value="contact.firstName"}}<br />
    Lasst Name: <input type="text" id="txtLastName" {{bindAttr value="contact.lastName"}}<br />
    Email: <input type="text" id="txtEmail" {{bindAttr value="contact.email"}}<br />
</script>

<script type="text/x-handlebars" data-template-name="contact-table-row">
    <tr>
        <td>
            <img {{bindAttr src="contact.imageUrl" alt="contact.fullName" title="contact.fullName"}} width="50" height="50" /><br />{{contact.fullName}}
        </td>
        <td>
            Twitter: {{#if contact.twitter}}<a {{bindAttr href="contact.twitter"}} target='_blank'>Follow on Twitter</a>{{else}}-{{/if}}<br />
        </td>
        <td>
            <a href="#" {{action contactDetails context="contact"}}>Details</a> | 
            <a href="#" {{action contactEdit context="contact"}}>Edit</a> 
        </td>
    </tr>
</script>

:不明な点がある場合は、コメントセクションで質問してください。詳細を編集できます。

編集:このプロジェクトをGitHubに追加しましたが、学習サンプルとして公開したいものにはほど遠いです。目標は、この上で進歩し、近い将来にCRUDテンプレートを作成することです。現在MSWebAPIを使用していますが、Railsバージョンがまもなく追加される可能性があります。

4

1 に答える 1

9

ここで起こっていることがいくつかあります、私はそれらに答えようとします、しかし私が何かを逃すならば、コメントを残してください。あなたはEmberがすでにあなたのために行っている多くのことを再発明しているようです。

まず、ビューをconnectOutletメソッドに渡したい場合は、唯一の引数としてハッシュを渡す必要があります。

router.get('applicationController').connectOutlet({
  viewClass: App.EditContactView,
  controller: router.get('contactsController'),
  context: context
})

第二に、2つのコンタクトコントローラーを持つことは眉をひそめません、実際私はそれをお勧めします。から継承する単数形とからContactController継承する単数形。これは、組み込みのコンテンツプロキシを簡単に利用できることを意味します。ObjectControllerContactsControllerArrayController

第三に、モデルにメソッドを追加findしてfindAllクラス化すると、自分の生活がはるかに楽になります。

  • 定義したシリアル化/逆シリアル化メソッドを定義する必要はありません。デフォルトでは、Emberはルートから推定された名前のモデルを検索するため、:contact_idは自動的にApp.Contact.find(:contact_id)を検索します。

  • インデックスconnectOutletsを次のように変更することもできます。router.get('applicationController').connectOutlet('contacts', App.Contact.findAll())

もう1つのヒント、現在、詳細と編集ルートはほぼ完全に同じです。と呼ばれる単一のルートを作成してcompanyから、子の詳細を作成し、その中のビューを編集します。

于 2012-07-08T12:20:23.653 に答える