无法将具有特征的父组件的选定数据数组传递给嵌套组件 [英] Unable to pass an array of selected data from parent component with traits to the nested component

查看:76
本文介绍了无法将具有特征的父组件的选定数据数组传递给嵌套组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  • App/Http/Livewire
  1. UserController-Livewire/UserManagement/UserController
  2. WithBulkActions-Livewire/特性/数据表/WithBulkActions

  • 资源/视图/直播
    1. 用户控制器刀片-livewire/用户管理/用户控制器

    说明

    我正在创建一个CRUD系统,其中包含删除所选数据的大量操作.我已经提取了负责选择多个项目或选择当前数据表中所有项目的逻辑,即UserController,因此我可以将其用作特征,即其他数据表组件中的WithBulkActions.该特征仅负责选择多个项目或从数据表中选择所有项目.数据表组件控制器本身(即UserController)中提供了删除数据数组的公共函数方法.现在,要使带有批量操作的多重选择生效,我必须在数据表组件刀片视图(即UserController刀片视图)中包括确认模式,该模式负责触发删除数据数组的方法.当我包含确认模式以删除用户控制器中的选定数据时,它可以完美地工作.尽管每一行都有一个复选框,其样式为 wire:model =" selected" ,其中的 value =" {{$ user-&id; id}}" foreach循环.在特征WithWithBulkActions中,将公共变量 selected 初始化为 public $ selected = []; ,然后在组件UserController中使用该特征.

    Description

    I am creating a CRUD system, with bulk actions to delete the selected data. I have extracted the logic which is responsible to select multiple items or to select all items in the current data table i.e UserController, so I can use it as a trait i.e. WithBulkActions, in other data table components. The trait is only responsible to select multiple items or to select all items from the data table. The public function method to delete an array of data, is present in the data table component controller itself i.e. UserController. Now, to make the multiple select with bulk actions work, I have to include the confirmation modal, which is responsible to fire the method to delete an array of data, in the data table component blade view i.e. UserController Blade. It works perfectly when I include the confirmation modal to delete the selected data inside the user controller. While each row has a checkbox modeled to wire:model="selected" with the value="{{ $user->id }}" within the foreach loop. The public variable selected is initialized as public $selected = []; within the trait, WithBulkActions and then the trait is being used in the component, UserController.

    rowsQuery 属性在带有过滤器的查询中从用户模型获取数据,对它进行排序并作为属性返回.

    rowsQuery property within the UserController component gets the data from the User model in a query with the filters, sorting and return it as a property.

    public function getRowsQueryProperty()
        {
            $query = User::query()
                ->when($this->filters['email'], fn($query, $email) => $query->where('email', 'like', '%'.$email.'%'))
                ->when($this->filters['role'], fn($query, $role) => $query->whereHas('roles', fn ($query) => $query->where('id', $role)))
                ->when($this->filters['search'], fn($query, $search) => $query->where('name', 'like', '%'.$search.'%'))
                ->when($this->filters['date-min'], fn($query, $created_at) => $query->where('created_at', '>=', Carbon::createFromFormat('d/m/Y', $created_at)))
                ->when($this->filters['date-max'], fn($query, $created_at) => $query->where('created_at', '<=', Carbon::createFromFormat('d/m/Y', $created_at)));
            
            return $this->applySorting($query);
        }
    

    然后将 rowsQuery 克隆到特征WithWithBulkActions中的 selectedRowsQuery 属性中.

    Then the rowsQuery is cloned in the selectedRowsQuery property within the trait, WithBulkActions.

    public function getSelectedRowsQueryProperty()
        {
            return (clone $this->rowsQuery)
                ->unless($this->selectAll, fn($query) => $query->whereKey($this->selected));
        }
    

    如果要选择一个数据数组并且应该删除所选数据,则由UserController组件负责的公共函数confirmDeleteBulk()对此负责,以下公共函数调用 selectedRowsQuery 属性,该属性在特征本身中初始化,然后执行delete()方法并进行相应的通知.

    If incase an array of data is being selected and the selected data should be deleted, the public function confirmDeleteBulk() is responsible for it, which is in UserController component, the following public function calls for selectedRowsQuery property, which is initialized in the trait itself, and then it executes the delete() method and notify accordingly.

    public function confirmDeleteBulk()
        {
            $deleteCount = $this->selectedRowsQuery->count();
            foreach ($this->selectedRowsQuery->get() as $queryRow) {
                $queryRow->roles()->detach();
            }
            $this->selectedRowsQuery->delete();
            $this->showUserBulkDeletionModal = false;
            $this->notify('You\'ve deleted '.$deleteCount.' users');
        }
    

    我尝试使用公共函数方法制作单独的livewire组件,以通过显示确认模式来删除所选数据,但无法将所选行数传递给位于Livewire/UserManagement/LogicalComponent/UserBulkDeletion的UserBulkDeletion嵌套组件..如果可能的话,请告诉我这种情况下的最佳用例.我们将非常感谢您的帮助,因为我从2周开始就一直在尝试这样做.

    I tried making a separate livewire component with public function method to delete the selected data by displaying a confirmation modal but I was unable to pass the selected number of rows to the UserBulkDeletion nested component located at, Livewire/UserManagement/LogicalComponent/UserBulkDeletion. Please tell me the best use case in this situation, incase if what I want is possible. Help will be really appreciated, as I'm trying to do this since 2 weeks now.

    上下文

    • Livewire版本:2.3.8
    • Laravel版本:8.24.0
    • 高山版本:2.8.0
    • 浏览器:Chrome
    • Livewire/UserManagement/UserController
    class UserController extends Component
    {
        use WithCachedRows, WithSorting, WithBulkActions, WithPerPagePagination;
    
        public User $user;
        public $showFilters = false;
        public $filters = [
            'search' => "",
            'email' => null,
            'role' => '',
            'date-min' => null,
            'date-max' => null,
        ];
    
        protected $listeners = ['sectionRefresh' => '$refresh'];
    
        public function toggleShowFilters()
        {
            $this->useCachedRows();
    
            $this->showFilters = ! $this->showFilters;
        }
    
        public function resetFilters() 
        {
            $this->reset('filters'); 
        }
    
        public function updatedFilters() 
        {
            $this->resetPage();
        }
        
        public function getRowsQueryProperty()
        {
            $query = User::query()
                ->when($this->filters['email'], fn($query, $email) => $query->where('email', 'like', '%'.$email.'%'))
                ->when($this->filters['role'], fn($query, $role) => $query->whereHas('roles', fn ($query) => $query->where('id', $role)))
                ->when($this->filters['search'], fn($query, $search) => $query->where('name', 'like', '%'.$search.'%'))
                ->when($this->filters['date-min'], fn($query, $created_at) => $query->where('created_at', '>=', Carbon::createFromFormat('d/m/Y', $created_at)))
                ->when($this->filters['date-max'], fn($query, $created_at) => $query->where('created_at', '<=', Carbon::createFromFormat('d/m/Y', $created_at)));
            
            return $this->applySorting($query);
        }
    
        public function getRowsProperty()
        {
            return $this->cache(function () {
                return $this->applyPagination($this->rowsQuery);
            });
        }
    
        public function getRolesProperty()
        {
            $roles = Role::all();
            return $roles;
        }
        
        public function render()
        {
            return view('livewire.backend.management.audience-management.user-controller', ['users' => $this->rows, 'roles' => $this->roles]);
        }
    }
    

    • Livewire/用户管理/LogicalComponent/UserBulkDeletion
    • class UserBulkDeletion extends Component
      {
          use WithCachedRows, WithBulkActions, WithSorting;
          
          public $showUserBulkDeletionModal = false;
          public User $user;
          public $filters = [
              'search' => "",
              'email' => null,
              'role' => '',
              'date-min' => null,
              'date-max' => null,
          ];
      
          protected $listeners = ['deleteUserBulk'];
      
          public function deleteUserBulk()
          {
              $this->useCachedRows();
      
              $this->showUserBulkDeletionModal = true;
          }
      
          public function confirmDeleteBulk()
          {
              $deleteCount = $this->selectedRowsQuery->count();
              
              foreach ($this->selectedRowsQuery->get() as $queryRow) {
                  $queryRow->roles()->detach();
              }
      
              $this->selectedRowsQuery->delete();
              $this->showUserBulkDeletionModal = false;
      
              $this->notify('You\'ve deleted '.$deleteCount.' users');
              $this->emit('sectionRefresh');
          }
      
          public function getRowsQueryProperty()
          {
              $query = User::query()
                  ->when($this->filters['email'], fn($query, $email) => $query->where('email', 'like', '%'.$email.'%'))
                  ->when($this->filters['role'], fn($query, $role) => $query->whereHas('roles', fn ($query) => $query->where('id', $role)))
                  ->when($this->filters['search'], fn($query, $search) => $query->where('name', 'like', '%'.$search.'%'))
                  ->when($this->filters['date-min'], fn($query, $created_at) => $query->where('created_at', '>=', Carbon::createFromFormat('d/m/Y', $created_at)))
                  ->when($this->filters['date-max'], fn($query, $created_at) => $query->where('created_at', '<=', Carbon::createFromFormat('d/m/Y', $created_at)));
              
              return $this->applySorting($query);
          }
      
          public function render()
          {
              return view('livewire.backend.management.audience-management.logical-component.user-bulk-deletion');
          }
      }
      

      • Livewire/特性/DataTable/WithBulkActions
      • trait WithBulkActions
        {
            public $selectPage = false;
            public $selectAll = false;
            public $selected = [];
        
            public function renderingWithBulkActions()
            {
                if ($this->selectAll) $this->selectPageRows();
            }
        
            public function updatedSelected()
            {
                $this->selectAll = false;
                $this->selectPage = false;
            }
        
            public function updatedSelectPage($value)
            {
                if ($value) return $this->selectPageRows();
        
                $this->selectAll = false;
                $this->selected = [];
            }
        
            public function selectPageRows()
            {
                $this->selected = $this->rows->pluck('id')->map(fn($id) => (string) $id);
            }
        
            public function selectAll()
            {
                $this->selectAll = true;
            }
        
            public function getSelectedRowsQueryProperty()
            {
                return (clone $this->rowsQuery)
                    ->unless($this->selectAll, fn($query) => $query->whereKey($this->selected));
            }
        }
        

        • 视图/livewire/用户管理/逻辑组件/用户批量删除
        • <div>
              <form wire:submit.prevent="confirmDeleteBulk">
                  <x-modal.confirmation wire:model.defer="showUserBulkDeletionModal">
                      <x-slot name="title">Delete User</x-slot>
          
                      <x-slot name="content">
                          @json($selected)
                          Are you sure you want to delete users? This action is irreversible!
                      </x-slot>
          
                      <x-slot name="footer">
                          <x-button.secondary wire:click="$set('showUserBulkDeletionModal', false)">Cancel</x-button.primary>
          
                          <x-button.primary type="submit">Delete</x-button.primary>
                      </x-slot>
                  </x-modal.confirmation>
              </form>
          </div>
          

          推荐答案

          要将值从一个Livewire组件传递到另一个,请使用事件.

          To pass values from one Livewire component to another use events.

          Livewire组件可以通过全局事件系统相互通信.只要两个Livewire组件都位于同一页面上,它们就可以使用事件和侦听器进行通信.

          Livewire components can communicate with each other through a global event system. As long as two Livewire components are living on the same page, they can communicate using events and listeners.

          在您的Livewire组件之一中,您触发类似这样的事件

          In one of your Livewire components you trigger an event like

          $this->event('usersToDelete', [ 1,2,3 ]);
          

          在另一个组件中,您可以监听此事件

          In another component you can listen for this event

          public class MyOtherComponent extends Component
          {
          
              protected $listeners = [
                'usersToDelete' => 'deleteUsers'
              ];
          
              public function deleteUsers(array $user)
              {
                // .. do something
              }
          }
          
          

          这篇关于无法将具有特征的父组件的选定数据数组传递给嵌套组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆