代码之家  ›  专栏  ›  技术社区  ›  Tejs

EmberJS-文本绑定不工作

  •  0
  • Tejs  · 技术社区  · 12 年前

    好的,让我先说一下,我对Ember完全陌生。我有一段有趣的时间,只是想让一个基本的绑定工作。这是我的相关代码:

    应用程序.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 回复  |  直到 12 年前
        1
  •  2
  •   Sarus    12 年前

    我担心你已经被Embers的一个命名惯例咬了,这通常是很棒的,因为它通常意味着一切正常,但如果你不知道,偶尔会咬你。

    Ember期望类或命名空间是大写的,而实例是小写的。当Ember看到 Foo 属性,它假设它是一个命名空间,然后将查找名为 食品 而不是控制器属性。

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

    这就是为什么你可以使用 食品 在模板中,它工作:

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

    但当你尝试使用 食品 作为绑定的一部分,它不起作用:

    <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,该属性来自控制器,并且在绑定中使用时不是全局的:

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

    这是一个Fiddle演示上面写的所有内容:

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

        2
  •  0
  •   Lux    12 年前

    这是因为在Ember中,财产应该以小写字母开头!大写字母是全局的。

    因此您可以简单地转换JSON before将其导入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;
    };