如何在编辑函数返回之外使用setAttributes

时间:2020-11-08 作者:philolegein

这可能只是不理解JavaScript/ESNext作用域或函数传递(或两者兼而有之)的简单情况,但我无法让setAttributes在primary之外工作;return“返回”;我的编辑功能。我在这个主题上尝试了无数不同的变体,下面两个是最接近的。首先,这似乎是一种工作,但可能存在范围界定问题。在第二种情况下,将函数传递给组件似乎不起作用。我尝试的第一件事就是使用它,试着从他们在gutenberg/image-editor.js 但这会导致奇怪的行为:

export default function Edit( props ) {
        const {
                attributes: { cwraggDataSourceType, cwraggDataSource,
                    cwraggLocalFile },
                setAttributes,
        } = props;
...
        const DataButton = ( ) => {
                return (<Button
                    isPrimary
                    onClick={ doValidate }>{ __("Validate",
                        \'cwra-google-graph-block\')}</Button>);
        }
...
        const doValidate = ( ) => { 
                console.log(\'DataSourceType\', cwraggDataSourceType); // logs "DataSourceType undefined ... this is fine
                console.log(\'DataSource\', cwraggDataSource); // logs the value previously saved in the attribute cwraggDataSource ... this is good
                console.log(\'LocalFile\', cwraggLocalFile); // always logs undefined, so the attribute isn\'t being saved
                console.log(\'Doing validation\');
                apiFetch( {
                    path: \'/cwraggb/v1/setremotedatasrc\',
                    method: \'POST\', 
                    data: { \'url\': cwraggDataSource,
                            \'type\': cwraggDataSourceType,
                            \'postId\': post_id } }
                ).then( ( localFileName ) => {
                        console.log("Working with ", localFileName); // logs "Working with tmptesty-ZatdoP.tmp" which is fine and means the API call worked
                        setAttributes( { cwraggLocalFile: localFileName } );
                        console.log(\'I still have \', localFileName); // still fine
                        console.log(\'cwraggLocalFile is \', cwraggLocalFile); // logs "cwraggLocalFile is undefined" so ... the setAttribute call didn\'t work?
                }).catch( ( error ) => {
                        console.log(\'doh!\'); // we never get here (yay!)
                });
        };

        return (
            <Fragment>
                <div>
                    <DataSrcSelectControl />
                    <DataButton />
                </div>
                <div>
                <TextControl
                    label={ __( \'Data URL\', \'cwra-google-graph-block\' ) }
                    help={ __( \'Enter the URL from which to get \'
                      + \'a JSON file with the data for the graph.\',
                      \'cwra-google-graph-block\') }
                    value={ cwraggDataSource }
                    onChange={ (dataSource) => {
                        setAttributes( { cwraggDataSource: dataSource } ) // this works fine
                    }} />
                </div>
                <div className={ "it_worked" }>Generating graph from
                  { cwraggDataSource }</div>
                <div>Local data source is { cwraggLocalFile }</div> // this outputs "Local data source is tmptesty-ZatdoP.tmp" after I press the button, but if I update and reload the page, it outputs "Local data source is" and the attribute is empty????
            </Fragment>
        );
}
按下按钮时,CWRAGGOLOCALFILE变量未成功记录到控制台(它记录undefined), 但是is 在中更新return 按钮按下后输出,但isn\'t 已保存(在我为帖子按“Update”后,它仍在那里,但当我重新加载页面时,它就消失了。我不知道这里发生了什么。似乎setAttribute调用既起作用又不起作用,所以…我想我有一些范围问题?

在做了很多手脚之后,我无法实现这一点,所以我尝试了另一种方法,类似于this, 他将setAttributes函数传递给他的主管。我认为我不应该这样做,因为他在一个明显不同的范围内做这件事,但我现在正在尝试任何事情:

        const doValidate = ( (localFileName, setAttributes) => {
                console.log(\'Was passed\', localFileName);
                console.log(\'Doing validation\');

                let dst = default_dst;
                if (cwraggDataSourceType) {
                        dst = cwraggDataSourceType;
                }

                console.log(\'Using dst \', dst);
                apiFetch( {
                    path: \'/cwraggb/v1/setremotedatasrc\',
                    method: \'POST\',
                    data: { \'url\': cwraggDataSource,
                            \'type\': dst,
                            \'postId\': post_id } }
                ).then( ( localFileName ) => {
                        console.log(\'API returned \', localFileName); // still works fine to here
                        setAttributes( { cwraggLocalFile: localFileName } );
                        console.log(\'Got local file name \', localFileName);
                        console.log(\'cwraggLocalFile is \', cwraggLocalFile);
                }).catch( ( error ) => {
                        console.log(\'doh!\', error); // but then we get here! It doesn\'t like setAttributes
                });
        });

        return (
            <Fragment>
                <div>
                    <DataSrcSelectControl />
                    <Button isPrimary
                            onClick={ doValidate( {cwraggLocalFile},
                                {setAttributes}) }>{
                                    __("Validate",
                                    \'cwra-google-graph-block\')}</Button>
...
尝试使用此方法时,错误处理程序会执行以下操作:

TypeError: setAttributes is not a function. (In \'setAttributes({ cwraggLocalFile: localFileName })\', \'setAttributes\' is an instance of Object)
(anonymous function) — edit.js:95
promiseReactionJob
所以,我想我传递的setAttributes函数不正确。但是,事实上,这种情况正在发生,并且在这里犯下了错误,但不是在上面的第一次尝试中,这让我觉得我在第一次尝试中更接近于以正确的方式做事。

你知道我做错了什么,或者如何在main以外的地方使用setAttibutes吗return 呼叫

1 个回复
SO网友:Lovor

关于这一点,我有点晚了,但对于任何寻找类似答案的人来说——在第一个例子中,我想说你没有定义cwraggDataSource 属性正确(未提供块定义代码)。如果属性定义不正确,则将其初始化为未定义。

至于第二个示例,您试图在事件函数中调用setAttributes,而在其中setAttributes超出了范围。