好的,所以让我先说一下我对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()
答案 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>
这是一个小提琴演示上面写的所有内容:
答案 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;
};