EmberJS - 文本绑定不起作用

时间:2014-03-31 21:51:36

标签: javascript data-binding ember.js

好的,所以让我先说一下我对Ember完全不熟悉。我正在尝试一个基本的绑定工作,这是一个有趣的时间。这是我的相关代码:

App.js

var App = Ember.Application.create({
    rootElement: '#emberApp'
});

和routes.js:

App.Router.map(function () {

});

App.IndexRoute = Ember.Route.extend({
    model: function () {
        return { Foo: 3 };
    }
});

然后这是我的HTML文档:

<div id="emberApp"></div>

<script src="~/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/handlebars.js"></script>
<script src="~/Scripts/ember-1.4.0.js"></script>
<script src="~/Scripts/EmberApp.js"></script>
<script src="~/Scripts/Routes.js"></script>

<script type="text/x-handlebars" data-template-name="index">
    <div>The current foo value: {{Foo}}</div>
    {{input valueBinding=Foo}}
</script>

预期的结果是,当我输入创建的输入字段时,模板中绑定的值会同时更改。它应该相当简单吧?我不得不遗漏一些东西。

模板正确呈现The current foo value: 3,并呈现文本字段。但是,在此字段中键入任何内容对上述绑定不起作用。我尝试使用valueBinding标记对其进行标记,并切换到Ember.TextField而不是input帮助程序。我还尝试创建一个自定义Ember.Object.extend类,并将其作为索引路径的模型返回。

为了将文本框值绑定到模板中的{{Foo}}值,我缺少什么?

编辑 - 好的,我已经发现它是因为变量的大写:foo有效,但不是Foo。这是为什么?

我希望收到类似于此的JSON结果:

 {
     RemoteUserId: 0,
     UserPhotoUrl: '....',
     RemoteUserName: 'Bob',
 }

我假设这意味着我需要通过为每个元素制作控制器包装来“隐藏”这些值?即:

 remoteUserId: function() {
      return this.get('RemoteUserId');
   }.property()

2 个答案:

答案 0 :(得分:2)

我害怕你被一个Embers命名惯例所困扰,这通常很棒,因为它通常意味着事情正常,但如果你不了解它,偶尔会咬你。

Ember期望Classes或Namespaces大写,并且实例是小写的。当Ember看到绑定中使用的Foo属性时,它假定它是一个命名空间,然后将查找名为Foo的全局变量而不是控制器属性。

当您在模板中使用{{Foo}}时,行为略有不同,因为Ember将首先检查当前上下文(控制器)以查看该属性是否存在。如果它确实使用了该值,否则它将假定它是一个命名空间并在全局范围内查找它。由于性能问题,绑定不像模板那样工作,因为您不希望在绑定中检查两个位置以查找可能非常频繁更新的值(如输入的文本框)。

这就是您可以在模板中使用Foo的原因:

<script type="text/x-handlebars" data-template-name="index">
    <!-- This works! -->
    <div>The current foo value: {{Foo}}</div>   
</script>

但是当你尝试使用Foo作为绑定的一部分时,它将不起作用:

<script type="text/x-handlebars" data-template-name="index">
     <!-- This doesn't work as Ember thinks Foo is global (i.e., a namespace) -->
     {{input valueBinding=Foo}}
</script>

您最好的选择是遵循ember约定并确保所有属性名称都以小写字符开头。但是,如果要继续使用控制器中以大写字符开头的属性,则需要明确告诉Ember该属性来自控制器,并且当您尝试在绑定中使用它时,该属性不是全局的:

<script type="text/x-handlebars" data-template-name="index">
     <!-- Tell Ember Foo is in the controller which is what we want-->
     {{input valueBinding=controller.Foo}}
</script>

这是一个小提琴演示上面写的所有内容:

  

http://jsfiddle.net/NQKvy/881/

答案 1 :(得分:0)

因为在Ember属性中应该以小写字母开头!大写字母是全局字母。

所以你可以简单地将你的JSON bevore转换为ember:

var decapitalize = function(source) {
  var result = {};
  for(var prop in source) {
    result[prop.substr(0,1).toLowerCase() + prop.substr(1)] = source[prop];
  }
  return result;
};
相关问题