Livewire组件以错误顺序渲染元素属性,并且破坏了wire:click事件。

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

Livewire component renders element attribute in wrong order and breaks the wire:click event

问题

I'm working on a livewire component that acts as a file browser.

Initially a list of files and folders is passed to the components blade, if the item is a directory an anchor is returned which changes the current path to the items name which essentially 'moves' into the folder by requesting the files for the new path.

If the item is a file, a checkbox is returned like so

<input wire:model="fileList" class="form-check-input" value="latest.log" type="checkbox">

Moving between folders and toggling checkboxes works on the first render without issues, however when moved into another directory the wire:click event is not fired anymore. After changing the components controller numerous times, I noticed that when the view is re-rendered, the checkbox is now returned, but the attributes are in a different order like so:

<input class="form-check-input" type="checkbox" value="latest.log" wire:model="fileList">

After moving between folders a few times, the checkboxes are returned as initially defined, and the wire:click event is working as well. What is causing this behavior? Why would the order change if it's strictly defined in a blade template for-loop like this;

@foreach ($files as $file)
    @if($file['attributes']['is_file'] == 'true')
        <input wire:model="fileList" class="form-check-input" value="{{ltrim($currentPath . '/' .  $file['attributes']['name'], '/')}}" type="checkbox">
    @else
        <a href="#" wire:click="updatePath('{{ $currentPath . '/' .  $file['attributes']['name'] }}')" class="link-danger"> {{ $file['attributes']['name'] }}</a>
    @endif
@endforeach

My components controller uses this function to move to a new folder;

public function updatePath($path)
{
    $this->currentPath = ltrim($path, '/');

    $this->getFiles();
    $this->render();
}

The getFiles() function is defined like so;

public function getFiles()
{
    //redacted
    $this->files = $apiRequest['data'];
}

It works as intended except for the checkboxes suddenly not firing an event anymore.

英文:

I'm working on a livewire component that acts as a file browser.

Initially a list of files and folders is passed to the components blade, if the item is a directory an anchor is returned which changes the current path to the items name which essentially 'moves' into the folder by requesting the files for the new path.

If the item is a file, a checkbox is returned like so

&lt;input wire:model=&quot;fileList&quot; class=&quot;form-check-input&quot; value=&quot;latest.log&quot; type=&quot;checkbox&quot;&gt;

moving between folders and toggeling checkboxes works on the first render without issues, however when moved into another directory the wire:click event is not fired anymore. After changing the components controller numerous of times I noticed the when the view is re-rendered the checkbox is now returned but the attributes are in a different order like so:

&lt;input class=&quot;form-check-input&quot; type=&quot;checkbox&quot; value=&quot;latest.log&quot; wire:model=&quot;fileList&quot;&gt;

After moving between folders a few times the checkboxes are returned as initially defined and the wire:click event is working as well. What is causing this behaviour? Why would the order change if its strictly defined in a blade templates for-loop like this;

@foreach ($files as $file)
    @if($file[&#39;attributes&#39;][&#39;is_file&#39;] == &#39;true&#39;)
        &lt;input wire:model=&quot;fileList&quot; class=&quot;form-check-input&quot; value=&quot;{{ltrim($currentPath . &#39;/&#39; .  $file[&#39;attributes&#39;][&#39;name&#39;], &#39;/&#39;)}}&quot; type=&quot;checkbox&quot;&gt;
    @else
        &lt;a href=&quot;#&quot; wire:click=&quot;updatePath(&#39;{{ $currentPath . &#39;/&#39; .  $file[&#39;attributes&#39;][&#39;name&#39;] }}&#39;)&quot; class=&quot;link-danger&quot;&gt; {{ $file[&#39;attributes&#39;][&#39;name&#39;] }}&lt;/a&gt;
    @endif
@endforeach

My components controller uses this function to move to a new folder;

public function updatePath($path)
    {
        $this-&gt;currentPath = ltrim($path, &#39;/&#39;);

        $this-&gt;getFiles();
        $this-&gt;render();
    }

the getFiles() functions is defined like so;

    public function getFiles()
    {
        //redacted
        $this-&gt;files = $apiRequest[&#39;data&#39;];
    }

It works as intended except for the checkboxes suddnly not fireing an event anymore.

答案1

得分: 0

你不需要在Wire:model中传递数值,它将不起作用。

protected $files = []; //首先声明它

@foreach ($files as $k => $file)
    @if ($file['attributes']['is_file'] == 'true')
        <input wire:model="fileList.{{$k}}" class="form-check-input" type="checkbox">
    @else
        <a href="#" wire:click="updatePath('{{ $currentPath . '/' . $file['attributes']['name'] }}')" class="link-danger"> {{ $file['attributes']['name'] }}</a>
    @endif
@endforeach
  1. 你需要设置数值,像这样:$this->files[0] = 'Your Value';,它也将在循环中使用。
public function getFiles()
{
    foreach ($apiRequest['data'] as $k => $v) {
        $this->files[$k] = ltrim($currentPath . '/' . $v['attributes']['name'] . '/');
    }
}
英文:

You Don't Need To Pass Value In Wire:model it will not work.

protected $files=[]; Declare It First 
@foreach ($files as $k=&gt; $file)
    @if($file[&#39;attributes&#39;][&#39;is_file&#39;] == &#39;true&#39;)
        &lt;input wire:model=&quot;fileList.{{$k}}&quot; class=&quot;form-check-input&quot;  type=&quot;checkbox&quot;&gt;
    @else
        &lt;a href=&quot;#&quot; wire:click=&quot;updatePath(&#39;{{ $currentPath . &#39;/&#39; .  $file[&#39;attributes&#39;][&#39;name&#39;] }}&#39;)&quot; class=&quot;link-danger&quot;&gt; {{ $file[&#39;attributes&#39;][&#39;name&#39;] }}&lt;/a&gt;
    @endif
 @endforeach
3. You need to set Value Like $this-&gt;files[0]=&#39;Your Value&#39;; 
It will also Be in loop 
   public function getFiles()
    {
        foreach($apiRequest[&#39;data&#39;] as $k=&gt;$v){
            $this-&gt;files[$k]=ltrim($currentPath . &#39;/&#39; .  $v[&#39;attributes&#39;][&#39;name&#39;] &#39;/&#39;)
        }
    }

答案2

得分: 0

问题已解决,我将自己回答。

添加一个唯一的 wire:key 可以跟踪输入:

<input wire:key="value.log" wire:model="fileList" class="form-check-input" value="latest.log" type="checkbox">

这也在 Livewire 的网站上有文档,我可能之前漏掉了它。

英文:

As I have fixed the issue I am just going to answer my own question.
Adding a unique wire:key allows keeping track of the inputs:

&lt;input wire:key=&quot;value.log&quot; wire:model=&quot;fileList&quot; class=&quot;form-check-input&quot; value=&quot;latest.log&quot; type=&quot;checkbox&quot;&gt;

This is also documented on livewire's website, I just must have missed it there.

huangapple
  • 本文由 发表于 2023年6月15日 04:00:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76477155.html
匿名

发表评论

匿名网友

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

确定