1

我有一个简单的 ember.js hello world,只有 1 条路线

(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 我收到错误

未捕获的类型错误:对象没有“创建”方法

环顾四周后,似乎最新的 ember 可能希望我首先在 ArrayController 上调用 .create({}),然后是 .extend({}),但我找不到任何使用 1.0 前版本的好例子。有谁知道我在上面可能做错了什么?

4

1 回答 1

3

这是一个有效的小提琴。http://jsfiddle.net/feCYT/4/

在 Ember pre 中,使用路由器逻辑,您extending可以ArrayController制作PersonApp.PersonController.

所以你PersonApp.PersonController是将军Class。您必须使用create此类的实例来处理数据。

Emberrouter会为你做这件事,作为路由器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 @Luke Melia:

正如您所指出的,您的事件处理程序示例并不理想。当应用程序初始化时,每个控制器实例都会将其目标属性设置为路由器。当视图处理像 insertNewLine 这样的浏览器事件时,它应该将其转换为发送到路由器的语义操作。例如 this.get('controller.target').send('addPerson', this.get('value'))。然后当前路由可以处理“addPerson”操作来修改模型和控制器,这反过来会触发数据绑定来更新视图,一切都会很好,没有任何全局变量。

于 2012-09-01T19:30:51.010 回答