복붙노트

[SPRING] 타임 라인 : 인라인 = "자바 스크립트"문제

SPRING

타임 라인 : 인라인 = "자바 스크립트"문제

다음과 같은 문제를 해결하는 방법을 모르겠습니다. 저는 모델이 일부 모델 논리를 기반으로 동적 인 실제 자바 스크립트를 생성하도록하고 싶습니다.

이 마지막 자바 스크립트 코드는 내 html 페이지의 $ (document) .ready {} 부분에 추가해야합니다.

문제는 : 인라인 = "javascript"를 사용하면 코드가 getter가 문자열이기 때문에 코드가 인용됩니다 (즉, Thymeleaf 문서에서 언급 된 방식이지만 필요하지는 않습니다.)

inline = "text"를 인용 부호로 사용하지 않으면 대신 모든 인용 부호가 이스케이프 처리됩니다 ;-) - 멋지지만 사용할 수 없습니다 8)

인라인 = "없음"을 시도하면 아무 일도 일어나지 않습니다.

여기에 예제가있다.

내 모델 getter는 다음과 같은 자바 스크립트 코드를 생성합니다.

PageHelper 클래스

public String documentReady() {

// do some database operations to get the numbers 8,5,3,2
return "PhotoGallery.load(8,5,3,2).loadTheme(name='basic')";

}

그래서 만약 내가 지금 인라인 = "자바 스크립트"

<script th:inline="javascript">
/*<![CDATA[*/
    jQuery().ready(function(){
        /*[[${pageHelper.documentReady}]]*/
    });
/*]]>*/
</script>

그것은에 렌더링됩니다

<script>
/*<![CDATA[*/
    jQuery().ready(function(){
        'PhotoGallery.load(8,5,3,2).loadTheme(name=\'basic\')'
    });
/*]]>*/
</script>

어느 것이 문자열 리터럴 (문자열 리터럴) 이건간에 도움이되지 않습니다 (Thymeleaf가 어떻게 처리하는지).

그래서 만약 내가 인라인 = "텍스트"대신에

<script>
/*<![CDATA[*/
    jQuery().ready(function(){
        PhotoGallery.load(8,5,3,2).loadTheme(name=&#39;basic&#39;)
    });
/*]]>*/
</script>

따옴표를 이스케이프합니다.

인라인 = "없음"아무것도 이해하지 못하기 때문에 나는 정말로 이해하지 못한다.

<script>
/*<![CDATA[*/
    jQuery().ready(function(){
        [[${pageHelper.documentReady}]]
    });
/*]]>*/
</script>

솔직히 나는 어떻게이 문제를 해결할 지 잘 모르겠다. 그리고 아무도 거기에 아무도 이것을 다루는 방법을 안다.

미리 감사드립니다. 건배 남자

해결법

  1. ==============================

    1.나는 접근 방식을 바꿀 것이다. Thymeleaf를 사용하면 템플릿에서 모델 변수를 쉽게 추가하여 Javascript에서 사용할 수 있습니다. 구현시 일반적으로 닫는 헤더 태그 앞에 어딘가에 변수를 넣습니다. JS가로드되면 페이지에 있는지 확인할 수 있습니다. 물론 템플릿이로드 할 대상을 결정하게합니다. 갤러리를 표시하고 있다면이를 렌더링하고 데이터 속성을 사용하여 일부 JS 코드와 관련된 갤러리를 정의하십시오. 그런 다음 자신의 멋진 jQuery 플러그인을 작성하여 갤러리를 처리하십시오.

    나는 접근 방식을 바꿀 것이다. Thymeleaf를 사용하면 템플릿에서 모델 변수를 쉽게 추가하여 Javascript에서 사용할 수 있습니다. 구현시 일반적으로 닫는 헤더 태그 앞에 어딘가에 변수를 넣습니다. JS가로드되면 페이지에 있는지 확인할 수 있습니다. 물론 템플릿이로드 할 대상을 결정하게합니다. 갤러리를 표시하고 있다면이를 렌더링하고 데이터 속성을 사용하여 일부 JS 코드와 관련된 갤러리를 정의하십시오. 그런 다음 자신의 멋진 jQuery 플러그인을 작성하여 갤러리를 처리하십시오.

    상대적으로 기본적인 예 :

    기본 레이아웃 장식 : layout / default.html

    <!doctype html>
    <html xmlns:layout="http://www.thymeleaf.org" xmlns:th="http://www.thymeleaf.org">
    <head>
      <title>My Example App</title>
      <object th:remove="tag" th:include="fragments/scripts :: header" />
    </head>
    <body>
      <div layout:fragment="content"></div>
      <div th:remove="tag" th:replace="fragments/scripts :: footer"></div>
      <div th:remove="tag" layout:fragment="footer-scripts"></div>
    </body>
    </html>
    

    여기서 주목해야 할 것은 제네릭 바닥 글 스크립트와 레이아웃을 포함하는 것입니다 : 조각 div 정의. 이 레이아웃 div는 갤러리에 필요한 jquery 플러그인을 포함하기 위해 사용할 것입니다.

    일반 스크립트 파일 : fragments / scripts.html

    <div th:fragment="header" xmlns:th="http://www.thymeleaf.org">
      <script type="text/javascript" th:inline="javascript">
        /*<![CDATA[*/
        var MY_APP = {
          contextPath: /*[[@{/}]]*/,
          defaultTheme: /*[[${theme == null} ? null : ${theme}]]*/,
          gallery: {
            theme: /*[[${gallery == null} ? null : ${gallery.theme}]]*/,
            images: /*[[${gallery == null} ? null : ${gallery.images}]]*/,
            names: /*[[${gallery == null} ? null : ${gallery.names}]]*/
          }
        };
        /*]]>*/
      </script>
    </div>
    <div th:fragment="footer" xmlns:th="http://www.thymeleaf.org">
      <script type="text/javascript" src="/js/jquery.js"></script>
      <script type="text/javascript" src="/js/my_app.js"></script>
    </div>
    

    스크립트 파일에는 데코레이터에 포함 된 2 개의 조각이 있습니다. 헤더 단편에는 유용한 JSON 레이어뿐만 아니라 defaultTheme도 포함되어 있습니다. 그러면 갤러리 객체가 정의되고 모델에서 할당됩니다. 바닥 글 조각은 jQuery 라이브러리와 기본 사이트 JS 파일을이 예제의 목적을 위해 다시로드합니다.

    게으른 로딩 된 갤러리가있는 페이지 : products.html

    <html layout:decorator="layout/default" xmlns:layout="http://www.thymeleaf.org/" xmlns:th="http://www.thymeleaf.org">
    <head>
      <title>Products Landing Page</title>
    </head>
    <body>
      <div layout:fragment="content">
        <h1>Products</h1>
        <div data-gallery="lazyload"></div>
      </div>
      <div th:remove="tag" layout:fragment="footer-scripts">
        <script type="text/javascript" src="/js/my_gallery.js"></script>
      </div>
    </body>
    </html>
    

    우리의 제품 페이지에는 그다지 많은 부분이 없습니다. 기본 장식자를 사용하여이 페이지는 헤드의 페이지 제목보다 우선합니다. 콘텐츠 조각에는 h1 태그의 제목과 데이터 갤러리 속성이있는 빈 div가 포함됩니다. 이 속성은 갤러리를 초기화하기 위해 jQuery 플러그인에서 사용할 것입니다. 값은 lazyload로 설정되므로, 우리 플러그인은 어딘가에있는 변수 세트에서 이미지 ID를 찾을 필요가 있음을 알고 있습니다. 우리 플러그인이 지원하는 유일한 것이 lazyloaded 갤러리 인 경우 이것은 쉽게 비어있을 수 있습니다.

    따라서 레이아웃은 일부 기본 스크립트를로드하고 독창적으로 배치 된 레이아웃 : 조각을 사용하여 사이트의 특정 섹션이 나머지 라이브러리와 독립적으로 라이브러리를로드하도록 허용합니다.

    다음은 Spring 컨트롤러의 기본 예제입니다. MyController.java

    @Controller
    public class MyController {
      @RequestMapping("/products")
      public String products(Model model) {        
        class Gallery {
          public String theme;
          public int[] images;
          public String[] names;
          public Gallery() {
            this.theme = "basic";
            this.images = new int[] {8,5,3,2};
            this.names = new String[] {"Hey", "\"there's\"", "foo", "bar"};
          }
        }
        model.addAttribute("gallery", new Gallery());
        return "products";
      }
    }
    

    갤러리 클래스는 여기 예제를 단순화하기 위해 제품 메소드에서 인라인으로 던져졌습니다. 이것은 식별자 나 필요한 배열을 반환하는 일부 유형의 서비스 또는 저장소 일 수 있습니다.

    우리가 만든 jQuery 플러그인은 my_gallery.js처럼 보일 수 있습니다.

    (function($) {
      var MyGallery = function(element) {
        this.$el = $(element);
        this.type = this.$el.data('gallery');
        if (this.type == 'lazyload') {
          this.initLazyLoadedGallery();
        }
      };
    
      MyGallery.prototype.initLazyLoadedGallery = function() {
        // do some gallery loading magic here
        // check the variables we loaded in our header
        if (MY_APP.gallery.images.length) {
          // we have images... sweet! let's fetch them and then do something cool.
          PhotoGallery.load(MY_APP.gallery.images).loadTheme({
            name: MY_APP.gallery.theme
          });
          // or if load() requires separate params
          var imgs = MY_APP.gallery.images;
          PhotoGallery.load(imgs[0],imgs[1],imgs[2],imgs[3]).loadTheme({
            name: MY_APP.gallery.theme
          });
        }
      };
    
      // the plugin definition
      $.fn.myGallery = function() {
        return this.each(function() {
          if (!$.data(this, 'myGallery')) {
            $.data(this, 'myGallery', new MyGallery(this));
          }
        });
      };
    
      // initialize our gallery on all elements that have that data-gallery attribute
      $('[data-gallery]').myGallery();
    }(jQuery));
    

    제품 페이지의 최종 렌더링은 다음과 같습니다.

    <!doctype html>
    <html>
    <head>
      <title>Products Landing Page</title>
      <script type="text/javascript">
        /*<![CDATA[*/
        var MY_APP = {
          contextPath: '/',
          defaultTheme: null,
          gallery: {
            theme: 'basic',
            images: [8,5,3,2],
            names: ['Hey','\"there\'s\"','foo','bar']
          }
        };
        /*]]>*/
      </script>
    </head>
    <body>
      <div>
        <h1>Products</h1>
        <div data-gallery="lazyload"></div>
      </div>
      <script type="text/javascript" src="/js/jquery.js"></script>
      <script type="text/javascript" src="/js/my_app.js"></script>
      <script type="text/javascript" src="/js/my_gallery.js"></script>
    </body>
    </html>
    

    보시다시피, Thymeleaf는 모델을 유효한 JS로 변환하는 작업을 훌륭하게 수행하고 필요한 곳에 따옴표를 실제로 추가하고 이스케이프 처리합니다. 페이지의 렌더링이 끝나면 파일 끝의 jQuery 플러그인을 사용하여 갤러리를 초기화하는 데 필요한 모든 항목을로드하고 준비가 완료되어야합니다.

    이것은 완벽한 예는 아니지만, 웹 앱을위한 매우 단순한 디자인 패턴이라고 생각합니다.

  2. ==============================

    2.$ {pageHelper.documentReady} 대신 $ {pageHelper.documentReady}를 사용하십시오.

    $ {pageHelper.documentReady} 대신 $ {pageHelper.documentReady}를 사용하십시오.

  3. from https://stackoverflow.com/questions/32596600/thymeleaf-thinline-javascript-issue by cc-by-sa and MIT license