Ember.js 如何在1.0之前的版本中创建和扩展Ember.ArrayController

Ember.js 如何在1.0之前的版本中创建和扩展Ember.ArrayController,ember.js,Ember.js,我有一个简单的ember.js hello world,它只有一条路线 (function() { window.PersonApp = Ember.Application.create({ ApplicationController: Ember.ObjectController.extend({}), ApplicationView: Ember.View.extend({ templateName: 'application' }),

我有一个简单的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模板非常基本,只需定义一个outlet和一个“home”视图,以按用户名显示用户

<!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>

使用者
{%load templatetag_Handlebar%}
{%verbatim%}
{{outlet}}
{%endverbatim%}
{%verbatim%}
{{view PersonApp.AddPersonTextField placeholder=“username”}
    {{{#每个人物pp.PersonController}
  • {{view PersonApp.RemovePersonCheckbox contentBinding=“this”checkedBinding=“isActive”} {{username}}
  • {{/每个}}
{%endverbatim%} 环境={ CP_默认值_可缓存:true, 视图保存上下文:true };
当这个运行时,我得到了错误

未捕获错误:断言失败:Ember.CollectionView的内容必须实现Ember.Array。您通过了PersonApp.PersonController

如果我尝试将Ember.ArrayController.extend切换到Ember.ArrayController.create,则会出现错误

未捕获的TypeError:对象没有“创建”方法


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

这是一把有效的小提琴

在Ember pre中,使用路由器逻辑,
扩展
阵列控制器
以生成
PersonApp.PersonController

因此您的
PersonApp.PersonController
是一个通用的
。您必须创建此类的
实例才能处理数据

Ember with
router
为您执行此操作,因为router
初始化它创建了当时可用的控制器实例。因此,您已经准备好了一个实例,
PersonApp.router.personController
请参见指示实例的person的小写字母

(值得一看DOM inspector上的“App.router”)

类似的函数应该需要一些更改,请参见注释行(这是一个快速修复):

这是一个快速修复,路由器的实际方式是,默认情况下,事件以路由器为目标,从路由器我们将它们委托给视图或控制器。深入研究路由器,找到这个

免责声明:这就是我的想法:)

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


正如您所指出的,您的事件处理程序示例并不理想。当应用程序初始化时,每个控制器实例都将其
target
属性设置为路由器。当视图处理类似于
insertNewLine
的浏览器事件时,它应该将其转换为发送到路由器的语义操作。e、 g.
this.get('controller.target').send('addPerson',this.get('value'))
。然后,当前路由可以处理“addPerson”操作以修改模型和控制器,这反过来会触发数据绑定以更新视图,并且一切都会很好,没有任何全局性的问题。@sabithpocker您能给我指一下显示这种方法的post或api文档吗?我以为余烬的会议是与控制者和控制者对话,与州经理对话?(谢谢!)@ToranBillups您可以查看文档和代码,这里是一些相关部分的要点我的第一个要点不确定它是否工作正常谢谢很棒的要点-解释了很多。最后一个问题-使用action Helper是否意味着双向绑定仍然有效,还是仅单向绑定?我不太理解这个问题,action Helper与任何绑定都没有直接关联。动作助手注册事件并将其委托给指定的目标,实际上您在哪里感到困惑?。这里还有一张@LukeMelia的幻灯片,您可能会感兴趣。
    AddPersonTextField: Ember.TextField.extend({
        insertNewline: function () {
            var value = this.get('value');
            if (value) {
                PersonApp.router.personController.addPerson(value);//check this
                this.set('value', '');
            }
        }
    }),