2009-11-22 44 views
17

Tôi đang cố sử dụng lệnh g.render trong dịch vụ grails, nhưng dường như g không được cung cấp cho các dịch vụ theo mặc định. Có cách nào để có được các động cơ templating để render một cái nhìn trong dịch vụ? Tôi có thể đi về điều này một cách sai lầm. Những gì tôi đang tìm đến là làm cho khung nhìn từ một phần mẫu thành một chuỗi và gửi chuỗi kết quả trở lại như là một phần của phản hồi JSON được sử dụng với các bản cập nhật AJAX.Sử dụng g.render trong dịch vụ grails

Mọi suy nghĩ?

+0

Đối với bất kỳ người tìm kiếm người đi lang thang trên này lo trang này nhiều năm sau đó, đừng quên rằng render một mẫu từ một phương tiện dịch vụ rằng khuôn mẫu sẽ không có cùng bối cảnh mà nó sẽ có nếu được kết xuất từ ​​một bộ điều khiển; vì vậy, nếu bạn đang sử dụng, ví dụ, 'createLink' trong GSP, bạn sẽ cần phải chỉ định' controller' cũng như 'action'! –

Trả lời

27

Tôi hoàn toàn đồng ý với lý lẽ của John - làm GSP trong các dịch vụ thường là một quyết định thiết kế tồi. Nhưng không có quy tắc nào ngoại trừ! Nếu bạn vẫn muốn làm điều này, hãy thử các phương pháp sau đây:

class MyService implements InitializingBean { 
    boolean transactional = false 
    def gspTagLibraryLookup // being automatically injected by spring 
    def g 

    public void afterPropertiesSet() { 
     g = gspTagLibraryLookup.lookupNamespaceDispatcher("g") 
     assert g 
    } 

    def serviceMethod() {  
     // do anything with e.g. g.render 
    } 
} 

Sử dụng đậu gspTagLibraryLookup bạn có thể truy cập tất nhiên mỗi taglib mong muốn khác trong một dịch vụ.

+0

với sức mạnh to lớn có trách nhiệm lớn lao! becareful khi làm những việc như thế này - chắc chắn rằng bạn biết lý do đằng sau rendering gsp trong một dịch vụ trước khi thực hiện nó :) – Chii

+0

Mục đích của tôi là render một khuôn mẫu và sau đó trở lại với JSON để HTML kết quả có thể được chèn vào. Tôi sẽ đóng gói logic trong một dịch vụ, nhưng thấy rằng chỉ cần trả về JSON theo cách thủ công trong mỗi bộ điều khiển cũng hoạt động tốt, và g.render đã có sẵn. Cảm ơn tất cả mọi người cho đầu vào của bạn. – aasukisuki

+0

Nó cũng có một vấn đề khác ... Thật khó để tạo ra các bài kiểm tra đơn vị cho các dịch vụ nếu chúng phụ thuộc vào bộ điều khiển. – luiscolorado

4

Lời khuyên của tôi là làm điều này trong bộ điều khiển. Dịch vụ phải có logic tái sử dụng và không phụ thuộc vào mẫu xem, hãy để công việc đó cho bộ điều khiển. Sử dụng dịch vụ để lấy dữ liệu bạn cần để chuyển tới mẫu, nhưng để lại công việc tương tác với mẫu tới bộ điều khiển.

+1

Xin lỗi, nhưng ngay cả khi câu trả lời của bạn là một lời khuyên tốt, nó không phải là một câu trả lời chấp nhận được: có nhiều cách để đạt được những gì đã được hỏi, ngay cả khi không được đề nghị. – Guillaume

3

Dưới đây là một giải pháp đó là tương tự như Stefan's, nhưng một chút đơn giản

import org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib 
import org.springframework.context.ApplicationContext 
import org.springframework.context.ApplicationContextAware 

class MyService implements ApplicationContextAware { 

    private ApplicationTagLib g 

    void setApplicationContext(ApplicationContext applicationContext) { 
     g = applicationContext.getBean(ApplicationTagLib) 

     // now you have a reference to g that you can call render() on 
    } 
} 
13

Nó thậm chí còn đơn giản hơn bây giờ trong Grails 2 với PageRenderer. ví dụ:

class SomeService { 
    def groovyPageRenderer 

    void someMethod() { 
     String html = groovyPageRenderer.render(view: '/email/someTemplateName') 
    } 
} 

API - http://grails.org/doc/latest/api/grails/gsp/PageRenderer.html

hoàn chỉnh hơn ví dụ - http://mrhaki.blogspot.com/2012/03/grails-goodness-render-gsp-views-and.html

+0

gần như đã bỏ lỡ câu trả lời của bạn, cảm ơn bạn đã thêm nó. trông mịn bây giờ với Grails mới – moeTi

+0

Dễ dàng và đơn giản. Nhưng [Stefan's] (http://stackoverflow.com/questions/1777640/using-g-render-in-a-grails-service/1778991#1778991) trả lời giải pháp cung cấp cho bất kỳ thẻ nào. Cảm ơn ;) – IgniteCoders

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