【问题标题】:Adding display data to model for controller ember.js将显示数据添加到控制器 ember.js 的模型
【发布时间】:2013-09-07 07:46:09
【问题描述】:

据我了解,控制器用于装饰数据或添加任何不属于模型(服务器)的数据。但是,我正在尝试了解如何将显示数据添加到模型数据中,以便我可以传递给 ember.js 中的模板

以下是代码示例。可能有更好的方法来做到这一点,但也许我让它变得更加困难。

当用户点击 div 时,我希望添加一个新的 css 'select' 类,以便点亮 div。

动作

  1. 用户点击 div
  2. userSelect 操作被触发,并且在控制器中 isSelected 设置为 true。这将更新模板并附加 'selected' 标记到类属性导致 div 为 已更新。

问题:

  1. 我想为模型中的每个用户添加一个显示属性 isSelected,而不仅仅是像我现在所做的那样添加到模型中。这可能吗?
  2. 目前,根据其实现方式,“已选择”标签仅在 isSelected = false 时才会显示。要么是逻辑相反,要么 isSelected 绑定到新值的顺序发生在模板渲染之后。

user.js

App.User = DS.Model.extend({
    firstName:     DS.attr('string'),
    lastName:      DS.attr('string')
});

App.User.FIXTURES = 
[
 {
   id:          1,
   firstName:   'Derek',
   lastName:    "H",

 },
 {
   id:          2,
   firstName:   'Test',
   lastName:    "H",

 }
]

UserListController.js

App.UserListController = Ember.ArrayController.extend({
    isSelected: false,
    userSelect: function(userId){

        this.set('isSelected', true);

        console.debug(userId + " isSelected:" + this.get('isSelected'));
    }
});

index.html

<script type="text/x-handlebars" id="userList" data-template-name="userList">
   {{#each controller}}  
        <div {{bindAttr class="isSelected:selected:notselected"}} {{action userSelect id}}>
         </div>
   {{/each}}
</script> 

我意识到我可以只操作 DOM 并附加类,但我想知道具体为 ember 执行此操作的正确方法。

任何建议表示赞赏, 谢谢 D

【问题讨论】:

    标签: model ember.js controller


    【解决方案1】:

    可以为模型添加属性。

    App.User = DS.Model.extend({
        firstName: DS.attr('string'),
        lastName: DS.attr('string'),
    
        isSelected: false
    });
    

    你的路线应该是这样的:

    App.UserRoute = Ember.Route.extend({
        model: function() { return App.User.find(); }
    });
    

    所以,我修改了你的模板:

     {{#each model}}  
        <div {{bindAttr class="isSelected:selected:notselected"}} 
             {{action 'userSelect' this}}>
        </div>
     {{/each}}
    

    还有控制器:

    App.UserController = Ember.ArrayController.extend({
        userSelect: function(user){
           user.set('isSelected', true);
        }
    });
    

    它应该可以正常工作。

    【讨论】:

    • 这不是我想走的路线,因为 isSelected 不是真正的服务器数据,而是更多的显示数据。谢谢你!
    • 不是服务器数据。如果要将属性指定为服务器数据,请设置 DS.attr('string') 或 Ember.attr('string')。它的设计目的是区分服务器数据和显示数据。
    • 这种方法可行但不推荐,isSelected 属性确实属于控制器而不是模型。理解为什么是微妙但重要的——虽然每个用户都有一个模型对象,但可能有很多控制器。该用户对象可能出现在一些列表中、搜索结果中、编辑页面上等。如果您将 isSelected 等应用程序状态属性放在模型上,它们将流血并导致非常难以调试的问题。
    【解决方案2】:

    这里的问题是isSelected 属性在App.UserListController 上,它代表列表而不是每个单独的用户。您有正确的想法 - 使用控制器来装饰模型对象 - 但要完成这项工作,您需要为每个用户创建一个控制器实例。这就是{{each}} helper's itemController property 的用途。

    查看这篇博文以获得很好的解释:

    http://gaslight.co/blog/intermediate-ember-controller-concepts

    【讨论】:

    • 我实际上尝试过这种方式,但是在将其应用于仅与模型关联的控制器时遇到了问题。稍后我会发布示例。
    【解决方案3】:

    希望我能很好地理解您的问题。

    我们可以在数组控制器中为单个对象设置属性。

    <script type="text/x-handlebars" id="userList" data-template-name="userList">
       {{#each controller}} 
           {{#if selected}}
               div {{bindAttr class="selected"}}></div>
           {{else}}
            <div {{bindAttr class="notselected"}} {{action userSelect this}}>
             </div>
          {{/if}}
       {{/each}}
    </script> 
    

    操作用户选择

    App.UserListController=Em.ArrayController.extend({
      userSelect:function(ob){
        this.map(function(o,i){
          Em.set(o,"selected",false);
          if(ob.id===o.id)
            Em.set(ob,"selected",true);
        });
      }
    });
    

    看看这个Bin。 看看这个Bin

    【讨论】:

      猜你喜欢
      • 2012-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-20
      • 2013-04-03
      • 2015-10-31
      • 1970-01-01
      相关资源
      最近更新 更多