无法读取未定义的 属性 'xxx.xxx'
Cannot read property 'xxx.xxx' of undefined
正在升级 meteor
(从 1.4 到 1.7)和 react
(从 15.3.2 到 16.8.6)。使用流星大气。
在处理删除指令的代码的一部分,控制台出现以下熟悉但毫无头绪的错误:
Uncaught TypeError: Cannot read property 'displayConfirmation' of undefined
at remove (ticket.js:48)
at onClick (list.jsx:180)
at HTMLUnknownElement.callCallback (modules.js?hash=199fa8ade393a4d3c92b5b590836441c4936d1d6:54371)
at Object.invokeGuardedCallbackDev (modules.js?hash=199fa8ade393a4d3c92b5b590836441c4936d1d6:54420)
at invokeGuardedCallback (modules.js?hash=199fa8ade393a4d3c92b5b590836441c4936d1d6:54475)
at invokeGuardedCallbackAndCatchFirstError (modules.js?hash=199fa8ade393a4d3c92b5b590836441c4936d1d6:54489)
at executeDispatch (modules.js?hash=199fa8ade393a4d3c92b5b590836441c4936d1d6:54572)
at executeDispatchesInOrder (modules.js?hash=199fa8ade393a4d3c92b5b590836441c4936d1d6:54597)
at executeDispatchesAndRelease (modules.js?hash=199fa8ade393a4d3c92b5b590836441c4936d1d6:57461)
at executeDispatchesAndReleaseTopLevel (modules.js?hash=199fa8ade393a4d3c92b5b590836441c4936d1d6:57470)
期望:删除前弹出确认对话框
部分代码如下:
components/list.jsx
...
onClick={() => actions.delete && remove()}><img src={require('/crm/images/icon_delete.png')}/> Delete all selected</span>
...
actions/ticket.js
import * as React from 'react';
import { push, goBack } from 'react-router-redux';
import { reset, SubmissionError } from 'redux-form';
import { notify, confirm } from '../../core/actions';
import {Tickets} from '../../../../lib/collections';
import {
SELECT_TICKETS, UNSELECT_TICKETS, CHANGE_TICKETS_PAGE, SORT_TICKETS,
LOAD_TICKET, UNLOAD_TICKET,
LOAD_ACTIVITIES, UNLOAD_ACTIVITIES,
CHANGE_CATEGORY, CHANGE_STATUS, CHANGE_DATE,
} from './actionTypes';
export default {
remove(context) {
const {Meteor, Store} = context;
let tickets = Store.getState().tickets.list.selectedTickets;
confirm.displayConfirmation(context, { // <-- It can't seem to recognize this
title: 'Removing Tickets',
message: "<p>Are you sure you want to delete below tickets?<ul>{tickets.map((ticket, i) => <li key={'msg-' + i}>{ticket.ticketNo}</li>)}</ul></p>",
callback: () => {
Meteor.call('tickets.delete', tickets.map(ticket => ticket._id), (err) => {
if (err) {
return;
}
notify.sendNotify(context, `${tickets.map(ticket => ticket.ticketNo).join(', ')} ${tickets.length > 1 ? 'have' : 'has'} been deleted.`);
unselect(context);
});
}
});
},
};
../../core/actions/index.js
import notify from './notify';
import confirm from './confirm';
export default {
notify,
confirm
};
../../core/actions/confirm.js
let dismissConfirmation = ({Store}) => {
Store.dispatch({
type: DISMISS_CONFIRMATION
});
};
export default {
displayConfirmation({Store}, {title, message, callback}) {
Store.dispatch({
type: DISPLAY_CONFIRMATION,
title,
message,
callback
});
},
dismissConfirmation,
confirm(context) {
let {Store} = context;
Store.getState().confirm.callback();
dismissConfirmation(context);
}
};
非常感谢任何帮助!
-- 编辑 --
已尝试将 confirm.js 更改为:
../../core/actions/confirm.js
export const dismissConfirmation = ({Store}) => {
Store.dispatch({
type: DISMISS_CONFIRMATION
});
};
export const displayConfirmation = ({Store}, {title, message, callback}) => {
Store.dispatch({
type: DISPLAY_CONFIRMATION,
title,
message,
callback
});
};
export const confirm = (context) => {
let {Store} = context;
Store.getState().confirm.callback();
dismissConfirmation(context);
};
但仍然出现相同的未定义错误。
如果我尝试在 actions/ticket.js 处将 confirm.displayConfirmation
更改为 displayConfirmation
,则会出现以下错误:
Uncaught TypeError: displayConfirmation is not a function
把你confirm.js换成这个
export const dismissConfirmation = ({Store}) => {
Store.dispatch({
type: DISMISS_CONFIRMATION
});
};
export const displayConfirmation({Store}, {title, message, callback}) {
Store.dispatch({
type: DISPLAY_CONFIRMATION,
title,
message,
callback
});
},
export const confirm(context) {
let {Store} = context;
Store.getState().confirm.callback();
dismissConfirmation(context);
}
现在您可以像这样在其他文件中导入这些函数
import {
displayConfirmation,
confirm,
dismissConfirmation
} from '../../core/actions';
您混淆了命名导出和默认导出的概念,请阅读这篇文章Named exports vs default exports
根据@mzparacha 的建议,以下是最终更改。
../../core/actions/confirm.js
export const dismissConfirmation = ({Store}) => {
Store.dispatch({
type: DISMISS_CONFIRMATION
});
};
export const displayConfirmation = ({Store}, {title, message, callback}) => {
Store.dispatch({
type: DISPLAY_CONFIRMATION,
title,
message,
callback
});
};
export const confirm = (context) => {
let {Store} = context;
Store.getState().confirm.callback();
dismissConfirmation(context);
};
但是在导入部分,改为如下所示:
actions/ticket.js
import * as confirm from '../../core/actions/confirm';
...
其余的仍然存在。像魅力一样工作。谢谢@mzparacha
正在升级 meteor
(从 1.4 到 1.7)和 react
(从 15.3.2 到 16.8.6)。使用流星大气。
在处理删除指令的代码的一部分,控制台出现以下熟悉但毫无头绪的错误:
Uncaught TypeError: Cannot read property 'displayConfirmation' of undefined
at remove (ticket.js:48)
at onClick (list.jsx:180)
at HTMLUnknownElement.callCallback (modules.js?hash=199fa8ade393a4d3c92b5b590836441c4936d1d6:54371)
at Object.invokeGuardedCallbackDev (modules.js?hash=199fa8ade393a4d3c92b5b590836441c4936d1d6:54420)
at invokeGuardedCallback (modules.js?hash=199fa8ade393a4d3c92b5b590836441c4936d1d6:54475)
at invokeGuardedCallbackAndCatchFirstError (modules.js?hash=199fa8ade393a4d3c92b5b590836441c4936d1d6:54489)
at executeDispatch (modules.js?hash=199fa8ade393a4d3c92b5b590836441c4936d1d6:54572)
at executeDispatchesInOrder (modules.js?hash=199fa8ade393a4d3c92b5b590836441c4936d1d6:54597)
at executeDispatchesAndRelease (modules.js?hash=199fa8ade393a4d3c92b5b590836441c4936d1d6:57461)
at executeDispatchesAndReleaseTopLevel (modules.js?hash=199fa8ade393a4d3c92b5b590836441c4936d1d6:57470)
期望:删除前弹出确认对话框
部分代码如下:
components/list.jsx
...
onClick={() => actions.delete && remove()}><img src={require('/crm/images/icon_delete.png')}/> Delete all selected</span>
...
actions/ticket.js
import * as React from 'react';
import { push, goBack } from 'react-router-redux';
import { reset, SubmissionError } from 'redux-form';
import { notify, confirm } from '../../core/actions';
import {Tickets} from '../../../../lib/collections';
import {
SELECT_TICKETS, UNSELECT_TICKETS, CHANGE_TICKETS_PAGE, SORT_TICKETS,
LOAD_TICKET, UNLOAD_TICKET,
LOAD_ACTIVITIES, UNLOAD_ACTIVITIES,
CHANGE_CATEGORY, CHANGE_STATUS, CHANGE_DATE,
} from './actionTypes';
export default {
remove(context) {
const {Meteor, Store} = context;
let tickets = Store.getState().tickets.list.selectedTickets;
confirm.displayConfirmation(context, { // <-- It can't seem to recognize this
title: 'Removing Tickets',
message: "<p>Are you sure you want to delete below tickets?<ul>{tickets.map((ticket, i) => <li key={'msg-' + i}>{ticket.ticketNo}</li>)}</ul></p>",
callback: () => {
Meteor.call('tickets.delete', tickets.map(ticket => ticket._id), (err) => {
if (err) {
return;
}
notify.sendNotify(context, `${tickets.map(ticket => ticket.ticketNo).join(', ')} ${tickets.length > 1 ? 'have' : 'has'} been deleted.`);
unselect(context);
});
}
});
},
};
../../core/actions/index.js
import notify from './notify';
import confirm from './confirm';
export default {
notify,
confirm
};
../../core/actions/confirm.js
let dismissConfirmation = ({Store}) => {
Store.dispatch({
type: DISMISS_CONFIRMATION
});
};
export default {
displayConfirmation({Store}, {title, message, callback}) {
Store.dispatch({
type: DISPLAY_CONFIRMATION,
title,
message,
callback
});
},
dismissConfirmation,
confirm(context) {
let {Store} = context;
Store.getState().confirm.callback();
dismissConfirmation(context);
}
};
非常感谢任何帮助!
-- 编辑 --
已尝试将 confirm.js 更改为:
../../core/actions/confirm.js
export const dismissConfirmation = ({Store}) => {
Store.dispatch({
type: DISMISS_CONFIRMATION
});
};
export const displayConfirmation = ({Store}, {title, message, callback}) => {
Store.dispatch({
type: DISPLAY_CONFIRMATION,
title,
message,
callback
});
};
export const confirm = (context) => {
let {Store} = context;
Store.getState().confirm.callback();
dismissConfirmation(context);
};
但仍然出现相同的未定义错误。
如果我尝试在 actions/ticket.js 处将 confirm.displayConfirmation
更改为 displayConfirmation
,则会出现以下错误:
Uncaught TypeError: displayConfirmation is not a function
把你confirm.js换成这个
export const dismissConfirmation = ({Store}) => {
Store.dispatch({
type: DISMISS_CONFIRMATION
});
};
export const displayConfirmation({Store}, {title, message, callback}) {
Store.dispatch({
type: DISPLAY_CONFIRMATION,
title,
message,
callback
});
},
export const confirm(context) {
let {Store} = context;
Store.getState().confirm.callback();
dismissConfirmation(context);
}
现在您可以像这样在其他文件中导入这些函数
import {
displayConfirmation,
confirm,
dismissConfirmation
} from '../../core/actions';
您混淆了命名导出和默认导出的概念,请阅读这篇文章Named exports vs default exports
根据@mzparacha 的建议,以下是最终更改。
../../core/actions/confirm.js
export const dismissConfirmation = ({Store}) => {
Store.dispatch({
type: DISMISS_CONFIRMATION
});
};
export const displayConfirmation = ({Store}, {title, message, callback}) => {
Store.dispatch({
type: DISPLAY_CONFIRMATION,
title,
message,
callback
});
};
export const confirm = (context) => {
let {Store} = context;
Store.getState().confirm.callback();
dismissConfirmation(context);
};
但是在导入部分,改为如下所示:
actions/ticket.js
import * as confirm from '../../core/actions/confirm';
...
其余的仍然存在。像魅力一样工作。谢谢@mzparacha