【问题标题】:Using Repository in edit method Repository is null在编辑方法 Repository 中使用 Repository 为 null
【发布时间】:2020-12-23 19:33:24
【问题描述】:

使用 laravel 7 /livewire 应用程序,我使用 Repository 制作了 crud,并且我得到了数据列表, 在 mount 事件中,我分配 protected var $FacilityRepository ,它在 render 方法中工作正常,

但在编辑方法中它为空,我得到了错误:

Call to a member function getById() on null

当用户点击“编辑链接”时

<?php

namespace App\Http\Livewire\Admin;

use App\library\CheckValueType;
use App\Settings;
use DB;
use Livewire\Component;
use App\Facility;
use Livewire\WithPagination;
use App\Repositories\Interfaces\FacilityRepositoryInterface;


class Facilities extends Component
{
    use WithPagination;

    public $form= [
        'name'=>'',
        'descr'=> '',
        'created_at'=> '',
        'is_reopen'       => false,
    ];

    public $current_facility_id;
    public $filter_name= '';
    public $updateMode = 'browse';

    protected $FacilityRepository;
    public function render()
    {
        $this->facility_rows_count = Facility
            ::getByName($this->filter_name, true)
            ->count();
        $backend_per_page = Settings::getValue('backend_per_page', CheckValueType::cvtInteger, 20);
        \Log::info( 'render -10 $this->FacilityRepository::' . print_r(  json_encode($this->FacilityRepository), true  ) );
        // line above logged as : [2020-09-04 16:46:26] local.INFO: render -10 $this->FacilityRepository::{}

        return view('livewire.admin.facilities.container', [
            'facilityDataRows' => $this->FacilityRepository->filterWithPagination(
                [
                    'name'=>$this->filter_name,
                ],
                $backend_per_page
            ),
            'facility_rows_count'=> $this->facility_rows_count
        ]); // this listing is rendered OK
    }


    public function mount(  FacilityRepositoryInterface $FacilityRepository  ) {
        $this->FacilityRepository = $FacilityRepository;
        \Log::info( '-101mount $this->FacilityRepository::' . print_r(  json_encode($this->FacilityRepository), true  ) );
        // line above logged as : [2020-09-04 16:46:26] local.INFO: -101mount $this->FacilityRepository::{}
    }


    public function edit($id)
    {
        \Log::info( '-1 edit $id::' . print_r(  json_encode( $id ), true  ) );
        \Log::info( '-1 edit $this->FacilityRepository::' . print_r( $this->FacilityRepository, true  ) );
        // line above logged as : [2020-09-04 16:46:28] local.INFO: -1 edit $this->FacilityRepository::
        // AND ERROR NEXT
        $this->form = $this->FacilityRepository->getById($id)->toArray();
        \Log::info( '-1023 $this->form ::' . print_r(  json_encode( $this->form ), true  ) );


        $this->current_facility_id = $id;
        $this->form['created_at'] = getCFFormattedDateTime($this->form['created_at']);
        $this->emit('facility_opened',[ 'mode'=>'edit', 'id'=>$id ]);
        $this->updateMode = 'edit';
    }

在模板编辑链接中定义为:

@foreach($facilityDataRows as $nextFacilityDataRow)
    <tr>
        <td class="text-right m-0">
            <a wire:click="edit({{$nextFacilityDataRow->id}})"
                class="p-1 a_edit_item_{{$nextFacilityDataRow->id}} a_link">
                {{$nextFacilityDataRow->id}}
            </a>
        </td>

...

为什么会出错以及如何解决?

修改#2:

  1. 如果我做

    类设施扩展组件 { ... 公共 $FacilityRepository; }

我有错误:

Livewire component's [admin.facilities] public property [FacilityRepository] must be of type: [numeric, string, array, null, or boolean]. Only protected or private properties can be set as other types because JavaScript doesn't need to access them.
  1. 我试图将方法编辑声明为:

    公共函数编辑( FacilityRepositoryInterface $facilityRepository, int $id) { // 你是这个意思吗? ... }

我有错误:

Call to a member function filterWithPagination() on null

当我显示数据列表时,在 render 方法中使用的方法 filterWithPagination。 哪种方式是正确的?

修改#3: 如果要修改:

public function render(FacilityRepositoryInterface $facilityRepository)
{

我有错误:

Declaration of App\Http\Livewire\Admin\Facilities::render(App\Repositories\Interfaces\FacilityRepositoryInterface $facilityRepository) should be compatible with Livewire\Component::render()

?

修改#4: 在模式下打开页面我有 2 个定义了惰性的输入,例如

            <dd class="horiz_divider_right_23" wire:model="form.title.lazy" x-data="{ name: '{{$form['name']}}'}">
                
                <input
                    x-model="name"
                    x-on:blur="$dispatch('name', name)"
                    id="name"
                    class="form-control editable_field admin_control_input"
                    placeholder="Enter descriptive name"
                    autocomplete=off
                >
                @error('form.name')
                <div class="validation_error">{{ clearValidationError($message,['form.'=>'']) }}</div> @enderror
            </dd>

当我在 blur ervent 上编辑一些字段时,我得到了同样的错误:

Call to a member function filterWithPagination() on null

错误描述中有 url:

VM5783:1 POST http://local-hostels3.com/livewire/message/admin.facilities 500 (Internal Server Error)

http://local-hostels3.com 是我的本地主机

我是否以某种方式覆盖消息方法?

"laravel/framework": "^7.0",
"livewire/livewire": "^1.3",

谢谢!

【问题讨论】:

    标签: laravel laravel-livewire


    【解决方案1】:

    受保护和私有属性不会在 Livewire 更新之间持续存在。一般来说,您应该避免使用它们来存储状态。

    https://laravel-livewire.com/docs/properties/#important-notes

    话虽如此,您可以再次使用依赖注入,只需传递您需要的任何内容(在本例中为FacilityRepositoryInterface)作为edit 方法的第一个参数。

    同样适用于render 方法,因此您可以完全跳过mount

    更正

    我原来答案的最后一点是错误的,你不能在渲染方法中使用 DI。

    所以在渲染中使用,使用mount方法,在编辑中使用,通过第一个参数带来。如果渲染在使用编辑后抱怨没有它,请保存到编辑内的受保护属性。

    最终代码,应该可以工作

    
    class Facilities extends Component
    {
      protected $FacilityRepository;
    
      public function mount(FacilityRepositoryInterface $FacilityRepository)
      {
        $this->FacilityRepository = $FacilityRepository;
      }
    
      public function render()
      {
        // use $this->FacilityRepository->...
      }
    
      public function edit(FacilityRepositoryInterface $FacilityRepository, $id)
      {
        $this->FacilityRepository = $FacilityRepository;
        // rest of the edit method from your code
      }
    }
    

    【讨论】:

    • 哪一个可以决定?请看修改#2:
    • 你得到的关于公共属性的错误是预料之中的,它在同一个链接中得到了解释,我在上面提供了。至于第二个错误,在您的示例中,该方法用于render。正如我上面指出的那样,您是否更新了该方法?之后不要忘记将呼叫更新为$facilityRepository-&gt;filterWithPagination(...)
    • 请看修改#3
    • 好吧,我想我错了,很抱歉,误解了文档。因此,对于初始渲染,通过mount 引入存储库并将其保存到受保护的属性中。对于edit,通过第一个参数将其引入。
    • 我假设这个错误来自生命周期钩子触发时,但我可能是错的。我会开始另一个问题,也许其他人可以提供帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-21
    • 1970-01-01
    • 2022-01-15
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多