开发者问题收集

在 angular 5 中调用 javascript 函数时出现引用错误

2018-07-19
228

每当路由发生变化时,我都会尝试在 angular 中从 .js 文件中调用其中一个函数。

这是我在 javascript 文件中的代码,我需要调用 angular 中的 appData 函数。

console.log(parsedJsonResponse);console.log(appData)console.logs 工作正常,并且我得到了 JSON 响应。

window.dataLayer = (function () {

  var dataCall = function () {
    return new Promise((resolve, reject) => {

      var xhttp = new XMLHttpRequest();
      xhttp.onreadystatechange = function () {
        if (this.readyState == 4) {
          if (this.status == 200) {
            resolve(this.responseText);
          } else {
            console.log(this.status + '.....' + this.statusText)
          }
        }
      };

      xhttp.open("GET", "http://localhost:4200/assets/sample.json", true);
      xhttp.send();
    })

  }

  dataCall().then((CallResponse) => {
    getData(CallResponse)

  });

  window.addEventListener("load", function (event) {
    appData();
  })

  var getData = function (cData) {
    jsonResponse = cData.replace(/'/g, '"');
    parsedJsonResponse = JSON.parse(this.jsonResponse);
    var appData = parsedJsonResponse['content']['copy$$' + applicationContent];

    console.log(parsedJsonResponse);
  }

我正在调用 appData 函数

  var appData = function (applicationContent) {
    var appData = parsedJsonResponse['content']['copy$$' + applicationContent];
    console.log(appData)
  }

  return {
    appData: appData,
    dataCall: dataCall

  }

}())

这是我在 angular 中调用该函数的代码。

在 angular 中调用此函数时,我收到 ReferenceError: parsedJsonResponse 未定义

constructor(private router:Router) {}

 ngOnInit(){
  this.router.events
  .filter(event => event instanceof NavigationStart)
  .subscribe((event: NavigationStart) => {
    dataLayer.appData();
   })

 };

出了什么问题?谢谢。

2个回答

parsedJsonResponse 变量应在所有函数之外声明,如果您要在不同函数中使用。否则 parsedJsonResponsegetData 函数的私有变量。

window.dataLayer = (function () {
   var parsedJsonResponse;
   // ...rest

接下来,您需要删除窗口加载事件内的函数调用。 appData()window load 中被调用,但数据仍在获取中,并且 parsedJsonResponse 没有内容。

window.addEventListener("load", function (event) {
    // appData();
})

getData 函数中删除 this ,因为 jsonResponse 是一个私有变量。

 parsedJsonResponse = JSON.parse(jsonResponse);

希望这会有所帮助。

编辑: 无论如何,我不鼓励使用外部 js 文件。尝试在 Angular 应用中使用服务。

更新: 您没有在 dataLayer.appData() 中传递参数。 您没有在 API 请求中正确处理异常。

Lasithe
2018-07-19

尝试在 dataLayer 函数内声明 parsedJsonResponse 变量:

window.dataLayer = (function () {
   var parsedJsonResponse;
   /* rest of your code */

编辑

发生这种情况的原因在于,当 ajax 响应来自服务器时,变量 parsedJsonResponse 会获取其值。这意味着,它依赖于异步操作。您可以做的就是等待承诺中的响应。我的建议是将该承诺保留在新变量 getAsyncData 中:

var getAsyncData = dataCall().then((CallResponse) => {
  getData(CallResponse)
});

也不要忘记将该变量添加到返回对象中:

return {
  appData: appData,
  dataCall: dataCall,
  getAsyncData: getAsyncData
}

您可以在您的 angular 应用中使用它,如下所示:

dataLayer.getAsyncData.then(() => {
 dataLayer.appData();
});

我注意到的另一件事是,您在 getData 函数中使用了 applicationContent,但它尚未在您的函数 dataLayer 中初始化。 appData 中该变量的唯一用法:

var appData = function (applicationContent) {

您还应该考虑在函数顶部初始化该变量。

window.dataLayer = (function() {
   var parsedJsonResponse;
   var applicationContent;
   /* rest of your code */

这是我在您的代码基础上稍作修改后编写的代码(这里我将响应发送到 jsonplaceholder 服务器,因此解析该响应不同,并且我还删除了 load 事件监听器:

https://jsbin.com/birofufade/edit?html,js,console,output

Azamat Zorkanov
2018-07-19