2017-12-08 12 views
0

원래 wagtail 문제 대기열에이 질문을했는데 잘못된 곳이라고 생각합니다. (비록 이것이 이것이 documentation의 버그라고 생각 하긴하지만)Wagtail : 하위 블록의 js_initializers도 실행되도록 맞춤 블록의 js_initializer를 어떻게 정의합니까?

어쨌든 내 문제는 내 안에 ListBlock을 사용하는 사용자 정의 StructBlock 클래스가 있다는 것입니다. 양식이 내 이니셜 라이저 ListBlock의 이니셜 라이저를 모두 트리거하도록하는 사용자 정의 클래스에 js_initializer() 메소드를 정의해야합니다.

# my_blocks.py 
class ImageGalleryBlock(blocks.StructBlock): 
    images = ListBlock(ImageChooserBlock(label='Image')) 

    def js_initializer(self): 
     return "ImageGallery" 

    @property 
    def media(self): 
     return forms.Media(
      js=['app/js/admin/image-gallery.js'] 
     ) 


# image-gallery.js 
function ImageGallery(prefix) { 
    // Set up the Image Gallery block's custom form behavior... 
} 

는 이쪽 ImageGallery() 기능을 실행할 수 있도록하지만, ListBlock의 초기화를 실행하지 않았기 때문에 그 버튼의 아무도 일하지 다음 docs에 따라

내 최초의 시도는이처럼 보였다. '

def js_initializer(self): 
    initializer_js = super(HeadingBlock, self).js_initializer() 
    my_custom_js = 'ImageGallery("%s")' % self.definition_prefix 
    if initializer_js: 
     # child blocks have custom JS initializers and need to be used 
     return '%s,\n%s' % (initializer_js, my_custom_js) 
    return my_custom_js 

# image-gallery.js 
function ImageGallery(prefix) { 
    var init_image_gallery = function(element_prefix) { 
    // Do stuff... 
    }; 

    return init_image_gallery; 
} 

내가 함수에 ImageGallery() 부분을 얻기 위해 원래의 제안에 대한 몇 가지 개선했습니다,하지만 여전히 아무튼 다음 할미새 문제 큐에

는,이 같은 것을 시도하는 것이 좋습니다했다 ListBlock 초기화 프로그램을 실행하십시오. 천국을 내가 실제로 DICT에 다른 키를 추가하기 만하면 무엇을 StructBlock로 전달되는 것을 느낌을 얻을

{ 
    'name': ('ImageGalleryBlock'), 
    'initializer': (StructBlock({ 
     'images': (ListBlock({ 
      'definitionPrefix': ('blockdef-63') 
     })) 
    }), 
    ImageGallery("blockdef-91")) 
}, 

하지만, I : 여기

ImageGalleryBlock에 대해 생성됩니다 이니셜 코드가 어떻게 생겼는지입니다 어떻게하면 가장 끔찍한 단서가 생겼어.

+0

은 [최소한의 완전하고 검증 가능한 코드 예제]를 포함하십시오 (https : //로 스택 오버플로.com/help/mcve) - StructBlock과 ListBlock이 어디에 있는지 알기 위해 ImageGalleryBlock을 충분히 공유하지 않았습니다. – gasman

+0

@gasman 아, 내 'ImageGalleryBlock' 정의가 조금 엉망이되었습니다. 너무 멀리 말하면, 당신은 말할지도 모른다. 지금 당장해야합니다. – CoreDumpError

답변

2

js_initializer 메서드는 페이지로드시 한 번 평가되고 함수를 출력하는 자바 스크립트 식을 반환합니다. 이 이니셜 라이저 함수는 블록이 양식에 삽입 될 때마다 호출되어 ID 접 두부를 전달하여 Javascript 비헤이비어를 수신해야하는 HTML 요소를 식별합니다. 이것은 두 단계 과정, 즉 페이지로드에 대한 초기 평가 (두 번째 단계에서 사용할 함수를 반환하는 함수 호출의 형태를 취함)와 각 블록에 대한 이니셜 라이저 함수를 호출하는 두 단계 프로세스라는 것을 이해하는 것이 중요합니다. 형태.

블록이 StructBlock과 마찬가지로 다른 블록의 래퍼 역할을 할 때마다이 계약이 하위 블록에 대해 적용되도록해야합니다. js_initializer이 페이지로드시 평가되는 경우 js_initializer이어야합니다. 그 시점에서 평가되고, 이니셜 라이저 함수가 호출 될 때, 그 자식 이니셜 라이저 함수를 호출합니다. 모두 StructBlock의 초기화 함수를 호출하는 하나의 함수로 평가하는 새로운 js_initializer 요구하고, 사용자 정의 이미지 갤러리 설정을 수행합니다 StructBlock 및 최우선 js_initializer 하위 클래스

, 당신은 효과적으로 StructBlock 주위에 배치의 또 다른 레이어를 추가하고 있습니다. 여기에 그렇게하는 방법은 다음과 같습니다

이미지 gallery.js :

/* ImageGallery gets called once on startup; the function it returns will 
be called whenever we need to set up an image gallery block on the form */ 
function ImageGallery(parentInitializer) { 
    return function(elementPrefix) { 
     /* call the original StructBlock initializer */ 
     parentInitializer(elementPrefix); 

     /* do whatever JS setup you need for the image gallery behaviour */ 
     $('#' + elementPrefix + '-gallery').doStuff(); 
    }; 
} 

my_blocks.py :

class ImageGalleryBlock(blocks.StructBlock): 
    images = ListBlock(ImageChooserBlock(label='Image')) 

    def js_initializer(self): 
     parent_initializer = super(ImageGalleryBlock, self).js_initializer() 
     return "ImageGallery(%s)" % parent_initializer 

    @property 
    def media(self): 
     # need to pull in StructBlock's own js code as well as our own 
     return super(ImageGalleryBlock, self).media + forms.Media(
      js=['app/js/admin/image-gallery.js'] 
     ) 
+0

이제 하나의 훌륭한 설명입니다! 모든 것이 마침내 효과가 있습니다! "js_initialiser()"에 사용 된 두 번째 "s"를 "z"로 바꾸어야 할 필요가 있었지만, 그 기능은 미국식으로 쓰여졌습니다. 나는 이것을 문서에 추가하는 것이 정말로 좋은 생각이라고 생각한다. – CoreDumpError