【问题标题】:How can I create a new record using Ember.js and ember-data?如何使用 Ember.js 和 ember-data 创建新记录?
【发布时间】:2012-07-22 03:00:30
【问题描述】:

我已经从我找到的各种文档和示例中编译了这个示例,但是我还没有找到使用路由器和 ember-data 来简单地创建新记录的完整示例,所以这是我的重头戏。

示例

http://jsfiddle.net/dmazza/Hb6BQ/4/

我有一个人 (DS.Model) 有名字和姓氏。

我有一个带有索引和创建路由的路由器,其中创建表单出现在 PeopleView 的出口中。

我使用 Ember.TextField 绑定到使用 App.Person.createRecord({}) 创建的新 Person 的属性,作为 PersonCreateController 的内容。

请注意,我有意按照@wycats 的建议为每个插座使用单独的控制器:https://github.com/emberjs/ember.js/issues/1050#issuecomment-6497907

问题

我似乎一遍又一遍地遇到同样的问题。我尝试使用 App.Person.find() 之类的方法,它会告诉我:

Uncaught TypeError: Cannot read property 'find' of undefined 

这将发生在:

  1. App.Person.find()
  2. App.Person.createRecord({})
  3. App.Store.find(App.Person)
  4. 其他几种方法(我会在想到它们时更新此列表)

问题

  1. 我是否使用这些工具以正确的方式创建新记录?
  2. 为什么会出现上述错误? (如果你打开你的网络检查器,你会看到这个错误,暂停未捕获的异常并确保你在结果(fiddle.jshell.net)框架中,而不是)

【问题讨论】:

    标签: ember.js ember-data ember-old-router


    【解决方案1】:

    我提出了一些类似的建议,请参阅http://jsfiddle.net/pangratz666/bb2wc/

    车把

    <script type="text/x-handlebars" data-template-name="application">
        <div class='container' id='application'>
            <header>
                <h1>People</h1>
            </header>
            <article>
                {{outlet}}
            </article>
        </div>    
    </script>
    
    <script type="text/x-handlebars" data-template-name="people">
        <ul>
            {{#each person in controller}}
                <li>{{person.firstName}} {{person.lastName}}</li>
            {{/each}}
        </ul>
        <button {{action newPerson }}>Create New Person</button>
        <hr/>
        {{outlet}}
    </script>
    
    <script type="text/x-handlebars" data-template-name="person_create">
        First name: {{view Ember.TextField valueBinding="firstName"}} <br/>
        Last name: {{view Ember.TextField valueBinding="lastName"}} <br/>
        <button {{action submitForm }}>Save</button>
        <button {{action cancel }}>Cancel</button>
        <h3>Current values: {{firstName}} {{lastName}}</h3>
    </script>
    

    ​JavaScript

    App = Ember.Application.create();
    
    App.Person = DS.Model.extend({
        firstName: DS.attr('string'),
        lastName: DS.attr('string')
    });
    
    // Note: these properties are expected to be dasherized
    App.Person.FIXTURES = [
        {
        "id": 1,
        "first_name": "Joe",
        "last_name": "Smith"},
    {
        "id": 2,
        "first_name": "James",
        "last_name": "Dolan"},
    {
        "id": 3,
        "first_name": "Jim",
        "last_name": "Carry"}
    ];
    
    App.Store = DS.Store.extend({
        revision: 4,
        adapter: DS.FixtureAdapter.create()
    });
    
    /*
     * Routing
     */
    App.Router = Ember.Router.extend({
    
        enableLogging: true,
    
        root: Ember.Route.extend({
            index: Ember.Route.extend({
                route: '/',
                connectOutlets: function(router, people) {
                    // set the content to all available persons
                    router.get('peopleController').set('content', App.Person.find());
                    router.get("applicationController").connectOutlet("people");
                },
                index: Ember.Route.extend({
                    route: '/'
                }),
                create: Ember.Route.extend({
                    route: '/create',
                    connectOutlets: function(router, person) {
                        // set/clear the content for the personCreateController
                        router.get('personCreateController').set('content', {});
                        router.get("peopleController").connectOutlet("personCreate");
                    },
    
                    // as proposed in https://github.com/emberjs/ember.js/pull/1139
                    exit: function(router) {
                        // called when we navigate away from this route: remove
                        // the connected outlet, which is the createPerson view
                        router.get('peopleController').set('view', null);
                    },
    
                    submitForm: function(router, event) {
                        // get the content of the personCreateController
                        var hash = router.getPath('personCreateController.content');
                        // create a new person
                        App.Person.createRecord(hash);
                        // navigate back to the index route
                        router.transitionTo('index');
                    },
    
                    // cancel button pressed
                    cancel: Ember.Route.transitionTo('index')
                }),
    
                // show the "dialog" for creating a new person
                newPerson: Ember.Route.transitionTo('create')
            })
        })
    });
    
    App.ApplicationController = Ember.Controller.extend();
    App.PeopleController = Ember.ArrayController.extend();
    App.PersonCreateController = Ember.ObjectController.extend();
    
    App.ApplicationView = Ember.View.extend({ templateName: 'application' });
    App.PeopleView = Ember.View.extend({ templateName: 'people' });
    App.PersonCreateView = Ember.View.extend({ templateName: 'person_create' });
    
    App.initialize();​
    

    【讨论】:

    • 感谢您的快速回复。看起来我犯的错误是因为我从路由器外部调用这些方法。感谢您提供有关取消和退出的额外提示!
    • 我试图了解在这种情况下应该如何使用控制器和视图。我想不出视图的用途,但我进行了修改以将新记录的实际创建放入控制器中。这看起来对吗? jsfiddle.net/dmazza/9QPjk/1
    【解决方案2】:

    随着 pre4 中引入的新 Ember 路由器,我想我会稍微更新一下这个答案。这对我有用(警告:CoffeeScript):

    App.Router.map ->
        @resource "posts", ->
            @route "new"
    
    App.PostsNewRoute = Ember.Route.extend
        setupController: (controller, model) ->
            controller.set 'content', {}
    
    App.PostsNewController = Ember.ObjectController.extend
        submitForm: (event) ->
            App.Post.createRecord @content
            @transitionToRoute 'posts.index'
    
    App.PostsNewView = Ember.View.extend
        controller: 'App.PostsNewController'
    

    我的模板看起来像这样:

        <script type="text/x-handlebars" data-template-name="posts/new">
          <div class="row">
            <div class="span12">
              <form class="create-post">
                <fieldset>
                  <legend>{{_ "Post"}}</legend>
                  <label>{{_ "Post Title"}}</label>
                  {{view Ember.TextField valueBinding="postTitle"}}
                  <!-- etc. etc. -->
                </fieldset>
              </form>
            </div>
          </div>
          <div class="row">
            <div class="span12 push-right">
              <a class="btn btn-primary" {{action "submitForm"}}>{{_ "Save"}}</a>
              {{#linkTo "posts.index" class="btn"}}{{_ "Cancel"}}{{/linkTo}}
            </div>
          </div>
        </script>
    

    我很想听听我的方法。

    【讨论】:

    • 这似乎是一种简单而干净的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多