2012-01-05 36 views
9

Tôi có hai lớp miềnmột danh sách các hộp kiểm

class Contract { 
    String number 
    static hasMany = [statements:Statement] 
} 

class Statement { 
    String code 
    static hasMany = [contracts:Contract] 
} 

Tôi muốn hiển thị tất cả các báo cáo có sẵn trong GSP của tôi với một hộp kiểm bên cạnh mỗi, cho phép người dùng chọn mà báo cáo được áp dụng cho hợp đồng. Vì vậy, một cái gì đó như:

[ ] Statement Code 1 
[ ] Statement Code 2 
[ ] Statement Code 3 

Tôi bắt đầu với điều này: Báo cáo

<g:each in="${Statement.list()}" var="statement" status="i"> 
    <g:checkBox name="statements[${i}].id" value="${statement.id}" checked="${contractInstance.statements.contains(statement.id)}" /> 
    <label for="statements[${i}]">${statement.code}</label> 
</g:each> 

Nhưng tôi chỉ không thể có được một danh sách các báo cáo kiểm tra với bộ điều khiển (có null yếu tố trong danh sách, có được lặp lại ...).

Bất kỳ ý tưởng nào để đạt được điều này?

Trả lời

6

Điều này là có thể, nhưng nó đòi hỏi một chút hack. Trước hết, mỗi hộp phải có cùng tên, "tuyên bố":

<g:each in="${org.example.Statement.list(sort: 'id', order: 'asc')}" var="statement" status="i"> 
    <g:checkBox name="statements" value="${statement.id}" checked="${contract.statements.contains(statement)}" /> 
    <label for="statements">${statement.content}</label> 
</g:each> 

Thứ hai, trong điều khiển bạn cần phải loại bỏ các "_statements" bất động sản trước khi ràng buộc: hỗ trợ hộp

def contract = Contract.get(params.id) 
params.remove "_statements" 
bindData contract, params 
contract.save(failOnError: true) 

Vui lòng cung chưa được thiết kế cho trường hợp sử dụng này, do đó cần phải hack. Hộp danh sách chọn nhiều là hộp danh sách thường được sử dụng cho loại kịch bản này.

+0

'params.remove" _statements "' đã thực hiện thủ thuật. Tuy nhiên tôi đã viết thẻ của riêng tôi mà xây dựng các hộp kiểm mà không có tham số _ ẩn. – zoran119

+0

Thật kỳ lạ khi các hộp kiểm đều cần có cùng tên, nhưng điều đó làm việc cho tôi! – adeady

0

Bạn có yêu cầu ánh xạ trực tiếp tới Contract không? Sẽ an toàn hơn nhiều khi ánh xạ yêu cầu đến vào một số Command object.

Về việc ánh xạ danh sách - các giá trị chỉ được ánh xạ tới các phần tử hiện có. Ý tôi là nó không thể tạo các phần tử danh sách mới. Bạn cần chuẩn bị trước khi lập bản đồ. Nếu bạn biết rằng luôn có 3 yếu tố, bạn có thể thực hiện:

class ContractCommand { 

    List statements = [ 
     new Statement(), 
     new Statement(), 
     new Statement(), 
    ] 
} 

và bản đồ theo yêu cầu để đối tượng này

1

Thay đổi hộp kiểm để một cái gì đó như thế này.

<g:checkBox name="statements.${statement.id}" value="true" checked="${contractInstance.statements.contains(statement)?:''}" /> 

và sau đó trong bộ điều khiển, trong params.statements bạn sẽ nhận được danh sách có ID của các câu lệnh đã chọn.

Cũng lưu ý ?:'' trong thuộc tính đã chọn, bạn nên thêm nó vì bất kỳ giá trị nào (thậm chí 'sai') trong thuộc tính đã chọn được hiểu là đã chọn.

+0

Sử dụng phương pháp này (và kiểm tra báo cáo 3, 4 và 6), 'params.statements' trông như thế này: 'statement: [_ 3 :, _4 :, _5 :, _6 :, _1 :, _2 :, 6: true, 4: true, 3: true]' và nó không liên kết với 'contractInstance'. Tất cả những gì tôi thực sự muốn là 'params.câu lệnh' là '[3, 4, 6]' trong trường hợp này. – zoran119

2

Cá nhân tôi muốn có danh sách các Id trong trường hợp này.

<g:each var="book" in="${books}"> 
    <g:checkBox name="bookIds" value="${book.id}" ... 
</g:each> 

lệnh Object:

class BookCommand { 
    List<Serializable> bookIds 
} 

Trong controller action:

BookCommand bc -> 
    author.books = Book.getAll(bc.bookIds) 
Các vấn đề liên quan