【问题标题】:Ember.js add css class for specific model idEmber.js 为特定模型 id 添加 css 类
【发布时间】:2016-04-17 14:42:29
【问题描述】:

我正在开发聊天应用程序。我有组件模板 - 房间

<div class='border rooms'>
    <button class="add-room-container">
        <div >Add room</div>
    </button>
    {{#each model as |room|}}
     <button class="room-container" 
             {{action "onRoomClicked" room.id}} 
             {{bind-attr class="currentRoomId===room.id:currentRoom"}}>
         <div class="deleteRoom" {{action "deleteRoom" room.id bubbles=false}}>
             X
         </div>
         <div>{{room.name}}</div>
         <div>{{room.createdAt}}</div>
     </button>
    {{/each}}
</div>

和组件js文件 从“ember”导入 Ember;

export default Ember.Component.extend({
  actions: {
    onRoomClicked(roomId) {
      this.set('currentRoomId', roomId);
    },
    deleteRoom(room) {
      console.log('room removed');
    }

} });

我的线路有问题

{{bind-attr class="currentRoomId===room.id:currentRoom"}}

我想检查当前按钮是否是最后一个被点击的按钮(它在 onRoomClicked 中设置),如果是,则将 currentRoom 类添加到按钮

我试图设置动态属性,但我不知道如何从组件中访问当前模型(房间)ID,然后像在模板中一样进行比较

【问题讨论】:

    标签: javascript html css ember.js


    【解决方案1】:

    你有很多不同的方法来做到这一点。但首先问题是您使用的是什么 ember 版本。在当前的 ember 版本中,不应再使用 bind-attr

    所以首先我假设你这样调用你的组件:

    {{my-component model=rooms}}
    

    我强烈建议不要调用您的数据model!给他们一个会说话的名字。做类似rooms=rooms的事情!

    所以现在你在你的组件中。您可能发现问题出在您的{{#each}} 循环上,这会导致您在{{#each}} 循环内没有用于上下文的.js 文件。


    也许最好的解决方法是使用第二个组件,您可以在每个循环中调用它:

    {{#each model as |room|}}
      {{room-line room=room currentRoomId=currentRoomId}}
    {{/each}}
    

    然后你可以把你的{{#each}} body 放在你的room-line.hbs 里面:

    <button class={{if isCurrentRoom "currentRoom"}}>
    ....
    

    你有一个支持room-line.js,你可以在其中计算isCurrentRoom

    isCurrentRoom: Ember.computed('currentRoomId', 'room.id', {
      get() {
        return get(this, 'currentRoomId')===get(this, 'room.id');
      }
    })
    

    解决此问题的另一种方法是将isCurrentRoom 注入您的room。这可以通过.map()ArrayProxy 和/或ObjectProxy 来完成。

    在你的组件.js 文件中有这样的东西:

    calculatedRooms: Ember.computed('rooms.@each.id', 'currentRoomId', {
      get() {
        return get(this, 'rooms').map(room => ({
          room,
          isCurrentRoom:get(room, 'id') === get(this, 'currentRoomId')
        }));
      }
    }),
    

    然后你可以在你的{{#each}}助手中使用它:

    {{#each calculatedRooms as |line|}}
       <button class="room-container {{if line.isCurrentRoom 'currentRoom'}}" 
         {{action "onRoomClicked" line.room.id}}>
        ...
    {{/each}}
    

    第三种方法是为此使用自定义助手。这可能是最简单的方法,但也可能是最丑陋的,因为您将逻辑放入模板中。

    一个简单的is-equal 助手可以帮助你:

    export function isEqual(a, b) {
      return a === b;
    }
    
    export default Ember.Helper.helper(=);
    

    然后你可以在你的模板中使用它:

    {{#each calculatedRooms as |room|}}
       <button class="room-container {{if (is-equal currentRoomId room.id) 'currentRoom'}}" 
         {{action "onRoomClicked" room.id}}>
        ...
    {{/each}}
    

    如果你选择这个方法,你可以使用ember-truth-helper,它提供了这个帮助,但你也可以自己写。


    我强烈推荐第一种方法,它是处理这个问题的最优雅的方法。

    【讨论】:

      【解决方案2】:

      最简单的方法是使用ember-truth-helpers,它在模板中为您提供了非常有用的eq 助手。然后你可以写:

      {{#each model as |room|}}
        <button
          class="room-container {{if (eq room.id currentRoomId) "currentRoom"}}" 
          {{action "onRoomClicked" room.id}}>
        </button>
      {{/each}}
      

      这是在您的类属性中使用嵌入的 if 帮助器,而不是 bind-attr (which is deprecated and you should avoid)。

      【讨论】:

      • 我也有同样的答案。不过,这个解释性更强。
      猜你喜欢
      • 2012-05-22
      • 1970-01-01
      • 2019-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多