我最初在wagtail问题队列中问了这个问题,我猜这是错误的地方。 (虽然我认为这是documentation中的一个错误。)
无论如何,我的问题是我有一个自定义StructBlock
类,里面有ListBlock
。我需要在自定义类上定义一个js_initializer()
方法,该方法会导致表单触发我自己的初始化程序和 ListBlock
的初始化程序。
我的初步尝试基于docs,看起来像这样:
# 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
的初始化程序,因此它的按钮都没有工作。
在wagtail问题排队中,我建议尝试这样的事情:
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
初始化程序。
以下是为ImageGalleryBlock
生成的初始化程序代码:
{
'name': ('ImageGalleryBlock'),
'initializer': (StructBlock({
'images': (ListBlock({
'definitionPrefix': ('blockdef-63')
}))
}),
ImageGallery("blockdef-91"))
},
我觉得我真正需要做的是为传递到StructBlock
的字典添加另一个键,但我没有得到最模糊的线索。
答案 0 :(得分:2)
js_initializer
方法返回一个Javascript表达式,在页面加载时评估一次,并吐出一个函数;每次将块插入表单时,都会调用此初始化函数,传递ID前缀以标识应接收Javascript行为的HTML元素。重要的是要理解这是一个两步过程 - 页面加载的初始评估(通常采用函数调用的形式,返回要在第二步中使用的函数),并为每个块调用初始化函数形式。
每当一个块作为其他块的包装器时,就像StructBlock那样,它负责确保为其子块强制执行此契约:当在页面加载时评估其自己的js_initializer
时,子{{ 1}}也需要在那时进行评估,并且当调用其初始化函数时,它会调用这些子初始化函数。
通过继承StructBlock并覆盖js_initializer
,您实际上在StructBlock周围添加了另一层包装:您的新js_initializer
需要评估一个函数,它们都调用StructBlock的初始化函数,并执行自定义图库设置。以下是如何做到这一点:
图像gallery.js:
js_initializer
my_blocks.py:
/* 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();
};
}