You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

运行browserify打包JS后调用collectQuestions方法提示未定义如何解决

问题根因
  • Browserify打包后的代码默认运行在独立闭包中,你导出的QuestionnaireView实例没有挂载到全局window对象上,Blazor JSInterop 仅能调用挂载在window下的全局方法/对象,自然找不到collectQuestions方法。
  • collectQuestions是类的实例成员方法,不能直接作为全局方法调用,必须先获取类实例,再通过实例调用该方法。
  • 现有代码存在隐藏bug:$j(this.options.questionId).each(function () {})使用普通函数作为回调,内部this指向已经改变,运行时会取不到this.options配置,哪怕方法能正常调用也会抛出异常。
  • 原有代码中answersAndWeightingsDict、weightingDict定义在循环外部,会导致所有问题共用同一个答案数组、所有返回结果共用同一个权重数组,返回数据会出现逻辑错误。

解决方案

第一步:修改JS代码,暴露实例到全局、修复逻辑问题

import $j from "jquery";
import BaseComponent from './Components/base-component';

class QuestionnaireView extends BaseComponent {
  constructor() {
    super();
    this.defaultOptions = {
      questionId : '#questionId',
      responseId : '#responseId',
      answerId : '#answerId',
      questionTextId : '#questionTextId'
    };
    this.state = {};
  }
  initChildren() {}
  addListeners() {}
  collectQuestions() {
    const questionAndAnswersDict = [];
    // 改用箭头函数修复this指向问题
    $j(this.options.questionId).each((index, questionEl) => { 
      const questionText = $j(questionEl).find("input")[0].value;
      // 将答案数组移到循环内部,避免不同问题共用同一份答案
      const answersAndWeightingsDict = []; 
      $j(this.options.answerId).each((index, answerEl) => {
        const answerText = $j(answerEl).find("input")[0].value;
        const weighting = $j(answerEl).find("input")[1].value;
        answersAndWeightingsDict.push({
          key: answerText,
          value: weighting
        });
      });
      questionAndAnswersDict.push({
        key: questionText,
        value: answersAndWeightingsDict
      });
    });
    // 增加返回值,供Blazor接收处理结果
    return questionAndAnswersDict; 
  }
  collectResponses() {
    const responsesDict = [];
    $j(this.options.responseId).each((index, responseEl) => {
      // 将权重数组移到循环内部,避免不同返回结果共用同一份权重
      const weightingDict = []; 
      const minWeighting = $j(responseEl).find("input")[0].value;
      const maxWeighting = $j(responseEl).find("input")[1].value;
      const responseText = $j(responseEl).find("input")[2].value;
      weightingDict.push({
        key: minWeighting,
        value: maxWeighting
      });
      responsesDict.push({
        key: responseText,
        value: weightingDict
      });
    });
    return responsesDict;
  }
}
// 实例化类并挂载到全局window对象,供Blazor JSInterop调用
window.QuestionnaireView = new QuestionnaireView();

第二步:安装依赖(若未安装)

确保本地已安装打包需要的所有依赖:

npm install --save-dev @babel/core @babel/preset-env @babel/preset-react @babel/plugin-transform-modules-commonjs babelify browserify

第三步:执行打包命令

原有带babelify的打包命令无需修改,直接执行即可:

browserify Scripts/questionnaire-view.js -o wwwroot/js/questionnaire-view.js -t [ babelify --presets [ @babel/preset-env @babel/preset-react ] --plugins [ @babel/plugin-transform-modules-commonjs ] ]

第四步:修改Blazor端调用方式

将原来直接调用方法名的逻辑,改为调用挂载到window上的实例方法:

// 错误的原有调用方式
// await JSRuntime.InvokeAsync<object>("collectQuestions");

// 修正后的调用方式
var questionList = await JSRuntime.InvokeAsync<object>("QuestionnaireView.collectQuestions");
var responseList = await JSRuntime.InvokeAsync<object>("QuestionnaireView.collectResponses");

验证步骤
  1. 打开打包后的wwwroot/js/questionnaire-view.js文件,搜索window.QuestionnaireView确认挂载逻辑存在
  2. 打开浏览器控制台,输入window.QuestionnaireView.collectQuestions,可以正常输出函数定义即说明挂载成功
  3. 触发Blazor端的调用逻辑,即可正常获取返回结果

内容的提问来源于stack exchange,提问作者James Blackburn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 09:30:03