Ajax 成功在页面加载时触发,而不是在触发 Ajax 调用之前。

huangapple go评论44阅读模式
英文:

Ajax success firing at page load, before triggering the Ajax call

问题

我在一个视图文件中有一个在函数内部的ajax调用(放在页面末尾)。在ajax成功时,我需要使用返回数据中的变量执行一些前端操作。

问题在于页面由于变量未定义而无法加载,但我不确定为什么在调用函数之前就需要定义它们。

这是成功函数:

```javascript
success: function (data, xhr) {
    var indexAttachment = $('#attachments').attr('data-attachment');
    if(xhr === 'success' && data['id'] !== null) {
        var id = data['id'];
        var fileName = data['fileName'];
        if(indexAttachment === null) {
            var indexAttachment = 0;
            $('#NoAttachments').remove();
        }
        indexAttachment++;
        var html = `<x-attachment id="${id}" index="${indexAttachment}" fileName="${fileName}" />`;
        $(html).hide().appendTo("#attachments").fadeIn(250);
    }
}

问题出在:

var html = `<x-attachment id="${id}" index="${indexAttachment}" fileName="${fileName}" />`;

我还尝试过不使用组件以及使用变量连接,像这样编码未定义的值:

var html = ''<x-attachment id="'+id+'" index="'+indexAttachment+'" fileName="'+fileName+'" />';

为了排除组件的影响,我尝试直接使用一个元素:

var html = `<span data-attachment="${id}"><a href="{{ route('document.download', [${id},preg_replace('/[^\w\-\.]/', '-', basename(${fileName})) ]) }}" name="{{ preg_replace('/[^\w\-\.]/', '-', basename(${fileName})) }}" id="document_${index}">${fileName}</a></span>`;

但结果出现了错误:
未定义常量“id”

这是函数内部完整的ajax调用:

var attachment = new FormData('#form);
$.ajax({
  async: false,
  type: "post",
  url: "{{ route('upload.attachment') }}",
  cache: false,
  processData: false,
  contentType: false,
  data: attachment,
  success: function (data, xhr) {
  var indexAttachment = $('#attachments').attr('data-attachment');
  if(xhr === 'success' && data['id'] !== null) {
    var id = data['id'];
    var fileName = data['fileName'];
    if(indexAttachment === null) {
      var indexAttachment = 0;
      $('#NoAttachments').remove();
    }
    indexAttachment++;
    var html = `<x-attachment id="${id}" index="${indexAttachment}" fileName="${fileName}" />`;
    $(html).hide().appendTo("#attachments").fadeIn(250);
  }
});

我在同一个函数中有另一个ajax调用,成功时也使用了另一个带有变量的组件,它按预期工作。

var html = `<x-note name="${createdBy}" text="${text}" index="${index}" />`;

值得一提的是,ajax调用的工作方式符合预期。

谢谢


<details>
<summary>英文:</summary>
I have an ajax call that is inside a function (pushed to the end of the page) in a view file. On ajax success, I need to perform some front-end manipulation using variables from the returned data.
The issue is that the page is not loading due to an error that the variables are undefined, but I am not sure why they would even be needed to be defined until the function is called.
This is the success function:

success: function (data, xhr) {
var indexAttachment = $('#attachments').attr('data-attachment');
if(xhr === 'success' && data['id'] !== null) {
var id = data['id'];
var fileName = data['fileName'];
if(indexAttachment === null) {
var indexAttachment = 0;
$('#NoAttachments').remove();
}
indexAttachment++;
var html = &lt;x-attachment id=&quot;${id}&quot; index=&quot;${indexAttachment}&quot; fileName=&quot;${fileName}&quot; /&gt;;
$(html).hide().appendTo("#attachments").fadeIn(250);
}
}


The issue is with:

var html = &lt;x-attachment id=&quot;${id}&quot; index=&quot;${indexAttachment}&quot; fileName=&quot;${fileName}&quot; /&gt;;


I have also tried not using the component as well as using variable concatenation like this and it encodes the undefined values at page load:

var html = '<x-attachment id="'+id+'" index="'+indexAttachment+'" fileName="'+fileName+'" />


To eliminate it being a component, I tried an element directly:

var html = &lt;span data-attachment=&quot;${id}&quot;&gt;&lt;a href=&quot;{{ route(&#39;document.download&#39;, [${id},preg_replace(&#39;/[^\w\-\.]/&#39;, &#39;-&#39;, basename(${fileName})) ]) }}&quot; name=&quot;{{ preg_replace(&#39;/[^\w\-\.]/&#39;, &#39;-&#39;, basename(${fileName})) }}&quot; id=&quot;document_${index}&quot;&gt;${fileName}&lt;/a&gt;&lt;/span&gt;;


Which results in an error:
`Undefined constant &quot;id&quot;`
Here is the complete ajax call inside the function:

var attachment = new FormData('#form);
$.ajax({
async: false,
type: "post",
url: "{{ route('upload.attachment') }}",
cache: false,
processData: false,
contentType: false,
data: attachment,
success: function (data, xhr) {
var indexAttachment = $('#attachments').attr('data-attachment');
if(xhr === 'success' && data['id'] !== null) {
var id = data['id'];
var fileName = data['fileName'];
if(indexAttachment === null) {
var indexAttachment = 0;
$('#NoAttachments').remove();
}
indexAttachment++;
var html = &lt;x-attachment id=&quot;${id}&quot; index=&quot;${indexAttachment}&quot; fileName=&quot;${fileName}&quot; /&gt;;
$(html).hide().appendTo("#attachments").fadeIn(250);
}
});


I have another ajax call in the same function with success using another component with variables and it works as expected. 

var html = &lt;x-note name=&quot;${createdBy}&quot; text=&quot;${text}&quot; index=&quot;${index}&quot; /&gt;;


I think it&#39;s worth noting that the ajax call is working as expected.
Thank you
</details>
# 答案1
**得分**: 1
```js
你的ajax似乎写错了。在`data`和`success`属性之间有一个大括号,可能会搞乱一切。
我不认为`&lt;x-attachment&gt;`会起作用。这是一个Blade组件,需要Blade编译器在页面加载之前评估和渲染它。当你的ajax完成后,它不会被重新评估以获取新值。
复制整个组件的定义也不是一个好主意,因为里面有很多PHP函数(`preg_replace`,`basename`),这些函数同样会在页面加载之前被评估。
英文:

Your ajax seems to be written wrong. You have a curly brace between the data and success properties that could be messing everything up.

var attachment = new FormData(&#39;#form&#39;);
$.ajax({
    async: false,
    type: &quot;post&quot;,
    url: &quot;{{ route(&#39;upload.attachment&#39;) }}&quot;,
    cache: false,
    processData: false,
    contentType: false,
    data: attachment,
    success: function (data, xhr) {
        var indexAttachment = $(&#39;#attachments&#39;).attr(&#39;data-attachment&#39;);
        if(xhr === &#39;success&#39; &amp;&amp; data[&#39;id&#39;] !== null) {
            var id = data[&#39;id&#39;];
            var fileName = data[&#39;fileName&#39;];
            if(indexAttachment === null) {
                var indexAttachment = 0;
                $(&#39;#NoAttachments&#39;).remove();
            }
            indexAttachment++;
            var html = `&lt;x-attachment id=&quot;${id}&quot; index=&quot;${indexAttachment}&quot; fileName=&quot;${fileName}&quot; /&gt;`;
            $(html).hide().appendTo(&quot;#attachments&quot;).fadeIn(250);
        }
    }
});

I don't think &lt;x-attachment&gt; would work though. It's a blade component that the blade compiler needs to evaluate and render before the page loads. It won't get re-evaluated when your ajax finishes with new values.

Copying the entire component's definition doesn't seem like a good idea either, since you have a lot of php functions in it (preg_replace, basename) that again, get evaluated before the page loads

答案2

得分: 1

经过一些调试,我相信我找到了问题所在。看起来 {{ route }} 命令试图渲染并寻找这些数值。将 route('document.download') 替换为路径而不是路由名称似乎修复了错误,但是数值仍然未定义。

在组件中我使用了以下代码:

&lt;a href=&quot;documents/{{$id}}/download/{{ preg_replace(&#39;/[^\w\-\.]/&#39;, &#39;-&#39;, basename($fileName)) }}&quot; name=&quot;{{ preg_replace(&#39;/[^\w\-\.]/&#39;, &#39;-&#39;, basename($fileName)) }} id=&quot;document_{{ $index }}&quot;&gt;{{ $fileName }}&lt;/a&gt;

我可能需要使用一个部分视图来填充这些数值。

英文:

After some tinkering, I believe I found the issue. It appears that the {{ route }} command is trying to render and is looking for the values. Replacing route('document.download') with the path instead of the route name seems to have fixed the error, but the values are still not defined.

This is what I used instead in the component:

&lt;a href=&quot;documents/{{$id}}/download/{{ preg_replace(&#39;/[^\w\-\.]/&#39;, &#39;-&#39;, basename($fileName)) }}&quot; name=&quot;{{ preg_replace(&#39;/[^\w\-\.]/&#39;, &#39;-&#39;, basename($fileName)) }} id=&quot;document_{{ $index }}&quot;&gt;{{ $fileName }}&lt;/a&gt;

I may have to use a partial view to get the values populated.

huangapple
  • 本文由 发表于 2023年2月6日 13:52:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75357757.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定