Livewire JavaScriptで全てのコンポーネントのプロパティを取得するには?

ショコラ
ショコラ

Livewire JavaScriptで全てのコンポーネントのプロパティを取得するには?

「コンポーネント.__instance.data」 で取得します。

もっさん先輩
もっさん先輩

「ページ上の全ての Livewire コンポーネントを取得する」には Livewire.all() を使います。

Livewire.all()

以下のようにすればコンポーネントのプロパティの値を取得することができますが、この component はどうも Proxy となっていて生のコンポーネントにアクセスしているわけではないみたいです。

for (let component of Livewire.all()) {
  console.log(component.count)
}

生のコンポーネントにアクセスするには __instance を使います。

component.__instance

生のコンポーネントを使えば、id にアクセスすることや、data、childIds、name にもアクセスすることができます。

for (let component of Livewire.all()) {
  console.log(component.__instance.id)
  console.log(component.__instance.data)
  console.log(component.__instance.childIds)
  console.log(component.__instance.name)
}

そして、今回のテーマ「JavaScriptで全てのコンポーネントのプロパティを取得するには?」は以下の Livewire.data関数 になります。

public/liveext.js

配置先:public/liveext.js

// window.Livewire は定義済みです。

const data = () => {
  return window.livewire.all().map(el => {
    const defer = new Map
    Object.keys(el.__instance.data).forEach(key => defer[key] = el.__instance.getPropertyValueIncludingDefers(key))
    return Object.assign(defer,{
      id: el.__instance.id,
      childIds: el.__instance.childIds,
      parentId: parentId(el.__instance.id)
    })
  })
}
const parentId = key => {
  let id = componentId(key)
  return window.livewire.all().find(el => -1 != el.__instance.childIds.indexOf(id))?.__instance.id
}
const componentId = key => window.livewire.all().find(el => -1 != [el,el.__instance,el.__instance.id,el.__instance.data.name].indexOf(key))?.__instance.id
const parent = key => window.livewire.find(parentId(key))
const syncBindings = () => window.livewire.emit('syncBindings',data())
export default {data,parentId,componentId,parent,syncBindings}

window.livewire.parentId = parentId
window.livewire.data = data
window.livewire.componentId = componentId
window.livewire.find = new Proxy(window.livewire.find,{
  apply(target,thisArg,argumentsList) {
    let key = argumentsList[0]
    let id = componentId(key)
    return target.apply(thisArg,[id])
  }
})
window.livewire.parent = parent
window.livewire.syncBindings = syncBindings
window.livewire.on('emitFind',(key,event,...params) => window.livewire.find(key).emitSelf(event,...params))
window.livewire.on('emitParent',(key,event,...params) => parent(key).emitSelf(event,...params))
window.livewire.on('createComponent',(html,target='body') => {
  const el = document.createElement('div')
  el.innerHTML = html
  document.querySelector(target).appendChild(el.firstElementChild)
  window.livewire.rescan()
})
window.livewire.on('removeComponent',key => {
  let id = componentId(key)
  document.querySelector(`[wire\\:id="${id}"]`).remove()
  window.livewire.rescan()
})
window.livewire.hook('component.initialized',component => {
  if (component.data.livedata) {
    component.addAction = new Proxy(component.addAction,{
      apply(target,thisArg,argumentsList) {
        let action = argumentsList[0]
        if (('method' in action.payload) && ('$' != action.payload.method.charAt(0)))
          action.payload.params.push(data())
        return target.apply(thisArg,[action])
      }
    })
  }
})

liveext.js のポイント
①Livewire.parentId関数で 親コンポーネントのID を取得できます。
②getPropertyValueIncludingDefers で defer に設定された値も取得できるように対応しました。
③Livewire.componentId関数で name から id を引けるようにしました。
④Livewire.find関数で name から find できるように変更しました。
⑤Livewire.syncProperties関数で 子供のプロパティが親のプロパティに同期できるようにしました。
⑥emitFindイベントで 特定のコンポーネントにイベントを送信できるようにしました。
⑦JavaScript のメソッド呼び出し時に、Livewire.data() を自動でパラメーターに追加するようにしました。
⑧createComponent、removeComponent を追加しました。コンポーネントを動的に作成、削除することができます。

resources/views/index.blade.php

<script type="module" src="/liveext.js"></script>

PHP側 で他のコンポーネントの値を参照する場合には、全てのコンポーネントのプロパティを Livewire.data() で送って参照してみようかなと思いました。

Livewire.data()

以上

Scroll to Top