java
  • jsp
  • jstl
  • 2009-09-29 38 views 73 likes 
    73

    tôi cần phải che giấu một yếu tố nếu giá trị nhất định có mặt trong JSPĐánh giá list.contains chuỗi trong JSTL

    Các giá trị được lưu trữ trong một danh sách vì vậy tôi cố gắng:

    <c:if test="${ mylist.contains(myValue) }">style='display:none;'</c:if> 
    

    Tuy nhiên, nó doesn 't làm việc.

    Làm cách nào để đánh giá liệu danh sách có chứa giá trị trong JSTL hay không, danh sách và giá trị là chuỗi.

    +13

    Lưu ý rằng cú pháp cho các công trình như intented từ EL 2.2 (trong trường hợp mang như một phần của Servlet 3.0/JSP 2.2 được phát hành tháng 12 năm 2009). – BalusC

    +0

    bản sao có thể có của [Bộ và Danh sách JSTL - kiểm tra xem mục có tồn tại trong Tập hợp hay không] (http://stackoverflow.com/questions/1076679/jstl-sets-and-lists-checking-if-item-exists-in-a -set) –

    Trả lời

    58

    Đáng buồn thay, tôi nghĩ rằng JSTL không hỗ trợ gì ngoài việc lặp lại qua tất cả các yếu tố để tìm ra điều này. Trong quá khứ, tôi đã sử dụng phương thức forEach trong thư viện thẻ lõi:

    <c:set var="contains" value="false" /> 
    <c:forEach var="item" items="${myList}"> 
        <c:if test="${item eq myValue}"> 
        <c:set var="contains" value="true" /> 
        </c:if> 
    </c:forEach> 
    

    Sau lần chạy này, $ {contains} sẽ bằng "true" nếu myList chứa myValue.

    +8

    hoạt động độc đáo nếu danh sách nhỏ. Chỉ cần nhận ra có một chi phí hiệu suất để làm điều đó theo cách này. – Chii

    +0

    Vâng, sẽ có nếu bạn đủ cao. Tôi đã sử dụng nó cho các bộ sưu tập 10-20 điều và chưa gặp phải bất kỳ vấn đề hiệu suất nào. Điều tôi nghĩ là tồi tệ hơn là số dòng của JSTL. Tuy nhiên, tôi nghĩ rằng đây là cách duy nhất mà không thiết lập TLD của riêng bạn (mà không phải là quá khó khăn và có thể rất tốt giá trị nó). –

    92

    không có tính năng tích hợp để kiểm tra điều đó - những gì bạn sẽ làm là viết hàm tld của riêng bạn có danh sách và một mục và gọi phương thức contains() của danh sách. ví dụ.

    //in your own WEB-INF/custom-functions.tld file add this 
    <?xml version="1.0" encoding="ISO-8859-1" ?> 
    <!DOCTYPE taglib 
         PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" 
         "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> 
    <taglib 
         xmlns="http://java.sun.com/xml/ns/j2ee" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" 
         version="2.0" 
         > 
        <tlib-version>1.0</tlib-version> 
        <function> 
         <name>contains</name> 
         <function-class>com.Yourclass</function-class> 
         <function-signature>boolean contains(java.util.List,java.lang.Object) 
         </function-signature> 
        </function> 
    </taglib> 
    

    Sau đó tạo một lớp được gọi là Lớp của bạn và thêm phương thức tĩnh có tên chứa chữ ký ở trên. Tôi chắc chắn việc thực hiện các phương pháp đó là khá tự giải thích:

    package com; // just to illustrate how to represent the package in the tld 
    public class Yourclass { 
        public static boolean contains(List list, Object o) { 
         return list.contains(o); 
        } 
    } 
    

    Sau đó, bạn có thể sử dụng nó trong jsp của bạn:

    <%@ taglib uri="/WEB-INF/custom-functions.tld" prefix="fn" %> 
    <c:if test="${ fn:contains(mylist, myValue) }">style='display:none;'</c:if> 
    

    Thẻ có thể được sử dụng từ bất kỳ JSP trong trang web.

    chỉnh sửa: biết thêm về các tập tin TLD - more info here

    +0

    : - S Mã được đặt ở đâu? Trông đe dọa – OscarRyz

    +1

    ive đã chỉnh sửa câu trả lời bằng một chút thông tin. – Chii

    +4

    Tôi khuyên bạn nên sử dụng 'Bộ sưu tập' thay vì' Danh sách' trong thẻ taglib - nó hoạt động giống nhau nhưng hỗ trợ nhiều loại bộ sưu tập như 'Set's – Ralph

    2

    Sau đây là chi tiết của một workaround hơn một câu trả lời cho câu hỏi của bạn, nhưng nó có thể là những gì bạn đang tìm kiếm. Nếu bạn có thể đặt giá trị của mình trong bản đồ thay vì danh sách, điều đó sẽ giải quyết được sự cố của bạn. Chỉ cần ánh xạ giá trị của bạn đến một giá trị null không và thực hiện điều này <c:if test="${mymap.myValue ne null}">style='display:none;'</c:if> hoặc thậm chí bạn có thể ánh xạ để style='display:none; và chỉ đơn giản là sản lượng ${mymap.myValue}

    +0

    Tôi đoán cú pháp phải là style = 'display: none;' Nếu không biến "myValue" không được đánh giá. – Andreas

    25

    Một cách khác để làm điều này là sử dụng một Map (HashMap) với cặp Key, Value đại diện cho đối tượng của bạn.

    Map<Long, Object> map = new HashMap<Long, Object>(); 
    map.put(new Long(1), "one"); 
    map.put(new Long(2), "two"); 
    

    Trong JSTL

    <c:if test="${not empty map[1]}"> 
    

    này sẽ trả về true nếu cặp tồn tại trong bản đồ

    +2

    Đây cũng là cách ưa thích của tôi, thiết lập hashmaps trong viewmodel cho mọi thứ tôi cần trong một khung nhìn. Chúng tích hợp độc đáo với cú pháp EL và nhanh như chớp khi tìm kiếm. –

    +0

    Chỉ một điều nữa, nếu khóa tồn tại nhưng giá trị là null hoặc rỗng thì nó sẽ trả về false. – Zai

    +1

    Hoặc nếu Bản đồ giữ các boolean, 'test =" $ {isPresentByValue [myValue]} "'. – Noumenon

    -3
    <c:if test="${fn:contains(task.subscribers, customer)}"> 
    

    này hoạt động tốt đối với tôi.

    +15

    Điều này đang thực hiện việc kiểm tra sau khi chuyển đổi cả hai thành phần thành chuỗi. Danh sách được chuyển đổi thành một chuỗi và không được kiểm tra trên cơ sở từng phần tử. Nếu task.subscribers là danh sách ["one", "two", "twentyone"], nó sẽ là: đúng cho khách hàng = "one" (khớp hai lần) false cho khách hàng = "ba" (không khớp) đúng cho khách hàng = "hai mươi" (mà không phải là những gì bạn đang tìm kiếm) – rmarimon

    +1

    Nhận thức được cảnh báo của rmarimon, câu trả lời này phù hợp với trường hợp sử dụng chính xác của tôi. – CodeReaper

    -1

    Nếu bạn đang sử dụng Spring Framework, bạn có thể sử dụng Spring TagLib và SpEL:

    <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> 
    --- 
    <spring:eval var="containsValue" expression="mylist.contains(myValue)" /> 
    <c:if test="${containsValue}">style='display:none;'</c:if> 
    
    -1

    Bạn cần phải sử dụng fn:contains() hoặc fn:containsIgnoreCase() chức năng.

    <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> 
    

    ...

    <c:if test="${not fn:containsIgnoreCase(mylist, 'apple')}"> 
         <p>Doesn't contain 'apple'</p> 
        </c:if> 
    

    hoặc

    <c:if test="${not fn:contains(mylist, 'Apple')}"> 
          <p>Contains 'Apple'</p> 
         </c:if> 
    
    +0

    @BalusC 1) Không có giới hạn trả lời câu hỏi được trả lời là SOF. 2) Hãy suy nghĩ trước khi bạn bỏ phiếu, câu trả lời này là chính xác và tôi đã kiểm tra điều này trước khi cung cấp câu trả lời. Tôi đã cập nhật câu trả lời để làm cho nó rõ ràng hơn. – tkr

    +0

    @BalusC Tôi không lặp lại và tôi chỉ cung cấp câu trả lời mở rộng. Tôi cũng không muốn muỗng cho người đọc ăn. Tôi nghĩ đó là toàn bộ điểm của SO. Trong SO, chúng tôi vẫn có thể trả lời câu hỏi liệu có câu trả lời được chấp nhận hay không. Nó không làm cho bất kỳ seance cho bạn. Và tôi cũng tôn trọng phiếu bầu của bạn vì tôi hiểu mọi người có hơn 100 đại diện hoặc có thể làm điều đó. Vì vậy, nếu bạn muốn đóng câu trả lời, vui lòng mở phiếu bầu. – tkr

    Các vấn đề liên quan