2

使用:

  • ember-1.0.0-pre.4.js
  • ember-data.jsリビジョン:11
  • ハンドルバー-1.0.rc.2.js

説明されている問題を説明するこのjsFiddleをご覧ください。

テンプレートに表示されるアイテムのリストがあります。テンプレートには、コントローラーがコレクションにアイテムを追加し、ページにテキスト入力として表示されるようにするlinkToヘルパーが含まれています。

コレクションへのアイテムの追加は、コントローラーによって行われます。

App.TodoItem = DS.Model.extend({
    title: DS.attr('string', { defaultValue: "unknown" })
});

App.Router.map(function () {
    this.resource('todo_items')
});

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

App.TodoItemsController = Em.ArrayController.extend({
    addTodoItem: function () {
        App.TodoItem.createRecord();
    }
});

新しいアイテムをリストに表示したい場合は、パラメータをに渡す必要createRecordがあります。そうしないと、アイテムが表示されません。Chromeのインスペクターを使用して同じ動作を再現すると、次のようにアイテムを表示できます。

// Open the jsFiddle http://jsfiddle.net/bazzel/BkFYd/ and select 'result(fiddle.jshell.net) in the inspector, then:
var item = App.TodoItem.createRecord();
// Nothing visible yet.

item.set('title', 'Whatever');
// Now the text input appear with the title as its value.

これは予想される動作ですか?もしそうなら、私はここで何が欠けていますか?

4

2 に答える 2

2

私はあなたの例を、Emberjsで適切に行われるべきだと私が感じる方法でやり直すのに時間をかけました。むしろ、トランザクションを確認し、ビューを適切に定義する必要があります。そうすれば、すべての問題が処理されます。だからこれがあなたがこれをすべきだと私が思う方法です

  • 入力されている値をキャプチャするか、モデルプロパティにバインドするために、テキストフィールドのビューを定義します。

  • アイテムのリストとリストへの新しいアイテムの追加は、2つの異なるビューで実行する必要があり、一緒に混合しないでください。

<script type="text/x-handlebars">
    {{outlet}}
    <div>
        {{outlet 'addItem'}}
    </div>
</script>

<script type="text/x-handlebars" data-template-name="todo_items">
    {{#linkTo 'todo_items.new'}}Add Todo Item{{/linkTo}}
  <ul>
    {{#each item in controller}}
        <li>
            {{#unless item.isNew}}
              {{item.title}}
            {{/unless}}
        </li>
    {{/each}}
    </ul>
</script>
  • アイテムを一覧表示し、新しいアイテムを追加するためのさまざまな状態を定義します

  • ObjectControllerテキストフィールド値をモデルプロパティに自動的にバインドするには、をTodoItemsNewルートに関連付ける必要があります

  • 最後に、トランザクションを利用してレコードを作成し、ストアにコミットします
window.App = Em.Application.create();

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

App.TodoItem.FIXTURES = [{
    id: 1,
    title: 'Lorem'
}, {
    id: 2,
    title: 'Ipsum'
}];

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

App.Router.map(function () {
    this.resource('todo_items',function(){
      this.route('new');
    })
});

App.IndexRoute = Em.Route.extend({
    redirect: function () {
        this.transitionTo('todo_items');
    }
});

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

App.TodoItemsNewRoute = Em.Route.extend({
    transaction: App.store.transaction(),

    setupController:function(controller) {
        console.info(controller.toString());
        controller.set('content',this.transaction.createRecord(App.TodoItem));
    },

    renderTemplate: function() {
        this.render('addItem',{
            into:'application',
            outlet:'addItem',
        })
    },
    events: {
      addItem: function() {
          this.transaction.commit();
            this.transitionTo('todo_items');
      }
    }
});


App.TodoItemsController = Em.ArrayController.extend();
App.TodoItemsNewController = Em.ObjectController.extend();
App.TextField = Ember.TextField.extend({
    insertNewline: function () {
      this.get('controller').send('addItem')
    }
});

これは、 jsfiddleの例の作業バージョンです。うまくいけば、私はこの例であなたの問題のいくつかを明らかにするのを手伝いました。

于 2013-01-27T06:31:04.783 に答える
0

私の質問に答えてくれてありがとうケン。それは確かにEmberでこれを行うためのより適切な方法のように感じます。ただし、どこからどのオブジェクトにアクセスできるかを把握するのは難しいと思います...

あなたの例は、私のコードを書き直すように私を刺激しました。また、あなたのアプローチにいくつかの変更を加えました。

  • それがベストプラクティスかどうかはわかりませんstore。インスタンスを作成しません。代わりに、Storeクラスを定義します。
  • TodoItemsNewControllerのコンテンツは、対応するルートのmodelプロパティを呼び出すことによって設定されます。
  • TodoItemsNewRouteのrenderTemplateには、アウトレットキーのみが必要です。

    <script type="text/x-handlebars">
        {{outlet}}
    </script>
    
    <script type="text/x-handlebars" data-template-name="todo_items">
        {{#linkTo 'todo_items.new'}}Add Todo Item{{/linkTo}}
        <ul>
        {{outlet "addItem"}}
        {{#each controller}}
            <li>
            {{#unless isNew}}
                {{title}}
            {{/unless}}
            </li>
        {{/each}}
        </ul>
    </script>
    
    <script type="text/x-handlebars" data-template-name="todo_items/new">
        {{view Ember.TextField valueBinding="title" placeholder="Enter title"}}
    

    window.App = Em.Application.create();
    
    App.TodoItem = DS.Model.extend({
        title: DS.attr('string', {
            defaultValue: "unknown"
        })
    });
    
    App.TodoItem.FIXTURES = [{
        id: 1,
        title: 'Lorem'
    }, {
        id: 2,
        title: 'Ipsum'
    }];
    
    App.Store = DS.Store.extend({
        revision: 11,
        adapter: DS.FixtureAdapter.create()
    });
    
    App.Router.map(function() {
        this.resource('todo_items', function() {
            this.route('new');
        });
    });
    
    App.IndexRoute = Em.Route.extend({
        redirect: function() {
            this.transitionTo('todo_items');
        }
    });
    
    App.TodoItemsRoute = Em.Route.extend({
        model: function() {
            return App.TodoItem.find();
        }
    });
    
    App.TodoItemsNewRoute = Em.Route.extend({
        model: function() {
            return App.TodoItem.createRecord();
        },
        renderTemplate: function() {
            this.render({
                outlet: 'addItem'
            });
        }
    });
    
    App.TodoItemsNewView = Em.View.extend({
        tagName: 'li'
    });
    

更新された例はjsFiddleにあります。

どんなレビューでも大歓迎です。

于 2013-01-27T10:42:22.513 に答える