0

因此,我能够在视图中列出数据库中的所有用户,但我想按字母顺序和选项卡列出它们。例如,我将有一个“All”、“A”、“B”、“C”等选项卡。我想要发生的是,当用户单击“A”选项卡时,它只显示姓氏以“A”开头的用户。

我这样做的想法是这样的:

<ul class="tabs">
  <li><a href="#A">A</a></li>
  <li><a href="#B">B</a></li>
  <li><a href="#C">C</a></li>
  ...
</ul>
<div class="tabcontents">
  <div id="All">
    <nav>
      <ul>
        <g:each var="user" in="${users}" ID="">
          <li><g:link controller="user" action="profile" id="${user.employeeNumber}">${user.lastName}, ${user.firstName}</g:link></li>
        </g:each>
      </ul>
    </nav>
  </div>
  <div id="A">
    <nav>
      <ul>
        <g:each var="user" in="${users}" ID="A">
          <li><g:link controller="user" action="profile" id="${user.employeeNumber}">${user.lastName}, ${user.firstName}</g:link></li>
        </g:each>
      </ul>
    </nav>
  </div>
  ...
</div>

后端 UserController 包含类似

class UserController {

  def index() {
    def users = UserFeed.createCriteria().list {
      eq('lastName[0]', '${ID}')
    }
    render(view: 'index', model: [users: users])
  }

  def search() {
  }

  def results(String lastName) {
    def users = UserFeed.where { 
      lastName =~ "%${lastName}%" 
    }.list()
    return [ users: users,
         term: params.lastName,
         totalUsers: UserFeed.count() ]
  }

    def profile(String id) {
    def user = UserFeed.findByEmployeeNumber(id)
    render(view: 'profile', model: [user: user])
    }
}

所以想法是,当用户单击选项卡时,选项卡的字母被发送到控制器,在控制器中比较数据库中姓氏的第一个字母,如果匹配则添加到列表中。这可能吗?有没有一种巧妙的方法来做到这一点?

提前致谢!

编辑:我可以蛮力这样做,我只是想避免每个字母有 26 个用户组。

编辑2:我尝试过这样的事情,但无济于事

<div id="A">
  <nav>
    <ul>
      <g:each var="user" in="${users}">
        <g:if test="${user.lastName.charAt(0)} == 'A'">
          <li style="padding-left:5px;"><g:link controller="user" action="profile" id="${user.employeeNumber}">${user.lastName}, ${user.firstName}</g:link></li>
        </g:if>
      </g:each>
    </ul>
  </nav>
</div>

我已经验证 user.lastName.charAt(0) 打印出正确的字母,但无论出于何种原因,该g:if语句都不会将列表限制为 A。任何想法为什么?

4

1 回答 1

1

我认为一个很好的起点是使用易于渲染到选项卡中的模型。例如,控制器方法可以返回一个模型,该模型包含一个 Map,其中包含键的字母和每个字母下的用户的值。

从用户列表和所选字母开始,下面是一个如何在 Groovy 中创建这样一个 Map 的示例:

def selectedLetter = 'A'
def tabs = users
     .groupBy { it.lastName[0].toUpperCase() }
     .collectEntries { k, v -> [k, v.sort() {a, b -> a.lastName <=> b.lastName}] }   
     .collectEntries { k, v -> k == selectedLetter ? [k, v] : [k, null] }

这将返回一个稀疏映射;通过将所有其他人设置为空,仅包含所选字母的用户。接下来,返回一个包含选项卡的模型:

render(view: 'index', model: [tabs: tabs])

有了这样的模型,选项卡可以动态呈现,如下所示:

<ul class="tabs">
    <g:each var="letter" in="${tabs.keySet().sort()}">
        <li class="${tabs.letter != null ? 'active' : ''">
            <a href="#${letter}">${letter}</a>
        </li>
    </g:each>
</ul>

选项卡内容可以这样呈现:

<div class="tabcontents">
    <g:each var="letter" in="${tabs.keySet().sort()}">
        <div id="${letter}">
            <nav>
              <ul>
                <g:each var="user" in="${tabs.letter}">
                  <li><g:link controller="user" action="profile" id="${user.employeeNumber}">${user.lastName}, ${user.firstName}</g:link></li>
                </g:each>
              </ul>
            </nav>
        </div>        
    </g:each>  
</div>
于 2015-07-31T21:35:25.357 回答