如何确保Laravel Blade中的唯一ID?

时间:2019-06-05 18:52:59

标签: php laravel laravel-blade

假设我有一个刀片组件,例如:

<input type="text" id="foo" name="{{$name}}"/>
<script>
$('#foo').whatever
</script>

IRL,此组件要复杂得多。您可以想象一个长格式,其中包含许多字段,这些字段具有通用名称,例如namedescriptionowner ...

然后我多次使用此组件,我再次提出foreach,但我们可以想象到其他无法使用迭代器为组件提供ID的情况:

@foreach($items as $item)
    @component('foo')
    @endcomponent
@endforeach

如何确保id的唯一性?

一种可能不好的解决方案是使用局部变量:

@php($id = uniqid())
<input type="text" id="{{$id}}" name="{{$name}}"/>
<script>
$('#{{$id}}').change(whatever)
</script>

有更好的方法吗?

3 个答案:

答案 0 :(得分:3)

我会将项目传递给组件:

@component('foo', ['item' => $item])

您可以在其中执行以下操作:

<input type="text" id="foo_{{ $item->id }}"/>

答案 1 :(得分:1)

有同样的需求,找到了这个答案,正如OP所说,我更倾向于认为,由于组件需要它,所以它应该处理它。

我想出了这种选择。

// resources/views/components/button.blade.php
@php
    $yourLibNameId = uniqid();
@endphp

<button data-your-lib-name-id="{{ $yourLibNameId }}">{{ $slot }}</button>

@push("script")
    <script type="text/javascript" defer="true">
        document.addEventListener("DOMContentLoaded", function() {
            const button = document.querySelector("[data-your-lib-name-id='{{ $yourLibNameId }}']");

            if (button instanceof HTMLElement) {
                button.addEventListener("click", function() {
                    console.log("clicked");
                });

                // or do whatever needed to initialize the button...
            }
        });
    </script>
@endpush

总结:

  • 我不是依靠id属性,而是使用data-x属性不干扰id,并为使用此数据提供了适当的范围
  • 我假设用户将在其布局或视图的正确位置提供@push("script")指令

我将要为Material Components Web创建一个组件库,所以这就是我将要使用的内容(因此your-lib-name)。

希望它可以帮助人们将其组件保持尽可能孤立的状态。

答案 2 :(得分:1)

如果我们可以假设 ID 只需要在组件内被引用(例如,一个字段和一个标签一起),并且 ID 是什么其他任何地方都无关紧要,只要它是唯一的... uniqid 看起来像应该没问题,但您也可以使用 \Illuminate\Support\Str::random() 作为 ID 的一部分。显然,其中任何一个都会随着每次渲染而改变,我个人也喜欢包含一些有意义的文本(例如 'name_field_'.Str::random())。

或者,可以使用单例来生成和跟踪使用的 ID,并确保它们不会被重复使用。类似的东西:

class UniqueIdTracker
{
    protected $idTracking = [];
    public function __invoke($prefix)
    {
        $increment = $this->idTracking[$prefix] ?? 0;
        $this->idTracking[$prefix]++;
        return $prefix . $increment;
    }
}

然后用 app(\Namespace\UniqueIdTracker::class)('prefix_') 调用。 (这可以通过将其包装在辅助函数或其他东西中来改进)。

我还注意到 AlpineJS 可能非常适合 OP 的用例,因为脚本可以附加到没有 ID 的元素。