1

ルートが1つだけのシンプルなember.js hello worldがあります

(function() {

  window.PersonApp = Ember.Application.create({

    ApplicationController: Ember.ObjectController.extend({}),

    ApplicationView: Ember.View.extend({
      templateName: 'application'
    }),

    Person: Ember.Object.extend({
      username: null,
      isActive: false
    }),

    PersonController: Ember.ArrayController.extend({
      content: [],

      addPerson: function(username) {
        var person = PersonApp.Person.create({ username: username });
        this.pushObject(person);
      },

      removePerson: function(person) {
        this.removeObject(person);
      }
    }),

    AddPersonTextField: Ember.TextField.extend({
      insertNewline: function() {
        var value = this.get('value');

        if (value) {
          PersonApp.PersonController.addPerson(value);
          this.set('value', '');
        }
      }
    }),

    RemovePersonCheckbox: Ember.Checkbox.extend({
      content: null,
      change: function(event) {
        PersonApp.PersonController.removePerson(this.content);
      },
    }),

    HomeController: Ember.Controller.extend(),
    HomeView: Ember.View.extend({
      templateName: 'home'
    }),

    Router: Ember.Router.create({
      root : Ember.Route.extend({
        index: Em.Route.extend({
          route: '/',
          connectOutlets: function(router){
            router.get('applicationController').connectOutlet('home');
          }
        })
      })
    })

  });

  $(function() {
    PersonApp.initialize(PersonApp.Router);
  });

})();

私のhtmlテンプレートは非常に基本的なもので、単一のアウトレットと1つの「ホーム」ビューを定義して、ユーザーをユーザー名で表示するだけです

<!DOCTYPE html>
<html>
<title>Users</title>
<link href="{{ STATIC_URL }}css/default.css" rel="stylesheet" type="text/css">
<script src="{{ STATIC_URL }}script/vendor/jquery-1.7.2.js" type="text/javascript"></script>
<script src="{{ STATIC_URL }}script/vendor/handlebars-1.0.0.beta.6.js" type="text/javascript"></script>
<body>
{% load templatetag_handlebars %}

<script type="text/x-handlebars" data-template-name="application">
  <div class="container">
  {% verbatim %}
    {{outlet}}
  {% endverbatim %}
  </div>
</script>

<script type="text/x-handlebars" data-template-name="home">
  {% verbatim %}
  {{view PersonApp.AddPersonTextField placeholder="username"}}
    <ul>
      {{#each PersonApp.PersonController}}
        <li>
          <label>
            {{view PersonApp.RemovePersonCheckbox contentBinding="this" checkedBinding="isActive"}}
            {{username}}
          </label>
        </li>
      {{/each}}
    </ul>
{% endverbatim %}
</script>

<script type="text/javascript" >
ENV = {
  CP_DEFAULT_CACHEABLE: true,
  VIEW_PRESERVES_CONTEXT: true
};
</script>

<script src="{{ STATIC_URL }}script/vendor/ember-1.0.pre.js" type="text/javascript"></script>
<script src="{{ STATIC_URL }}script/app/person.js" type="text/javascript"></script>
</body>
</html>

これを実行すると、エラーが発生します

キャッチされないエラー: アサーションに失敗しました: Ember.CollectionView のコンテンツは Ember.Array を実装する必要があります。PersonApp.PersonController を渡しました

Ember.ArrayController.extend を Ember.ArrayController.create に切り替えようとすると、エラーが発生します

キャッチされていない TypeError: オブジェクトにメソッド 'create' がありません

周りを見回した後、最新の残り火では、最初に ArrayController で .create({}) を呼び出し、次に .extend({}) を呼び出すことを期待しているようですが、1.0 より前のリリースを使用してこれの良い例を見つけることができません。上記で私が間違っている可能性があることを誰かが知っていますか?

4

1 に答える 1

3

これが機能するフィドルです。http://jsfiddle.net/feCYT/4/

Ember preでは、ルーターロジックを使用してextendingArrayControllerを作成しPersonApp.PersonControllerます。

だからあなたPersonApp.PersonControllerは一般的Classです。createデータを処理するには、このクラスのインスタンスが必要です。

Ember withrouterはこれを行います。ルーターとして、その時点initializesで使用可能なコントローラーのインスタンスを作成します。これで、インスタンスの準備ができましたPersonApp.router.personController。インスタンスを示す人のスモールキャップスを参照してください。

(DOMインスペクターの `App.router'を見る価値があります)

のような機能は、コメント行を参照してください(これは簡単な修正です):

    AddPersonTextField: Ember.TextField.extend({
        insertNewline: function () {
            var value = this.get('value');
            if (value) {
                PersonApp.router.personController.addPerson(value);//check this
                this.set('value', '');
            }
        }
    }),

これは簡単な修正であり、ルーターの実際の方法は、イベントがデフォルトでルーターをターゲットにしており、ルーターからビューまたはコントローラーにイベントを委任します。これを見つけるためにルーターを深く掘り下げてください。

免責事項:これは私が思うことです:)

コメントbt@LukeMelia:

お気づきのとおり、イベントハンドラーの例は理想的ではありません。アプリケーションが初期化されると、各コントローラーインスタンスのターゲットプロパティがルーターに設定されます。ビューがinsertNewLineのようなブラウザイベントを処理する場合、それをルータに送信されるセマンティックアクションに変換する必要があります。例:this.get('controller.target')。send('addPerson'、this.get('value'))。次に、現在のルートはその「addPerson」アクションを処理してモデルとコントローラーを変更できます。これにより、データバインディングがトリガーされてビューが更新され、グローバルがなくてもすべて正常に機能します。

于 2012-09-01T19:30:51.010 に答える