在编辑任何输入时呈现数据表单列表?

Posted

技术标签:

【中文标题】在编辑任何输入时呈现数据表单列表?【英文标题】:In listing of data form is rendered when any input edited? 【发布时间】:2020-12-03 23:48:32 【问题描述】:

使用 livewire 1.3 / alpinejs 2.x.x 我用过滤器文本列出数据 和选择输入并单击“搜索”按钮我需要运行搜索时 单击“搜索”按钮。 但是,当文本/选择输入失去焦点而没有单击“搜索”按钮时,就会运行搜索。 我通过表单的电线看到它:加载块和日志文件中的 1 行,我在渲染方法中触发 那不是我需要的:我只需要点击“搜索”按钮来运行渲染方法。 我尝试使用 alpinejs,但失败了...... 在组件 app/Http/Livewire/Admin/AppNews.php 我有:

<?php

namespace App\Http\Livewire\Admin;

use Carbon\Carbon;
use Livewire\Component;
use App\News;
use Livewire\WithPagination;
use Livewire\WithFileUploads;

class AppNews extends Component

    use WithPagination;
    use WithFileUploads;

    public $filters = [
        'title' => '',
        'published' => '',
    ];
    ];
    public $uploaded_file_name;
    public $uploadedImageFilenameData;
    public $uploadedNewsImage;
    protected $listeners = ['fileUpload' => 'handleFileUpload'];


    public $current_news_id;
    public $updateMode = 'browse';

    public function render()
    
        \Log::info('-1 NewsRENDER $this->filters ::' . print_r($this->filters, true));
        $news_rows_count  = News
            ::getByTitle($this->filters['title'], true)
            ->getByPublished($this->filters['published'], true)
            ->count();
        $backend_per_page = Settings::getValue('backend_per_page', CheckValueType::cvtInteger, 20);
        $this->emit('app_news_opened', ['mode' => 'browse', 'id' => null]);

        $newsPublishedValueArray = SetArrayHeader([['key' => '', 'label' => ' -Select published- ']], News::getNewsPublishedValueArray(true));
        $newsDataRows = News
            ::getByTitle($this->filters['title'], true)
            ->getByPublished($this->filters['published'], true)
            ->with('creator')
            ->orderBy('news.created_at', 'desc')
            ->paginate($backend_per_page);

        $newsDataIds = [];
        foreach ($newsDataRows as $nextNews) 
            $newsDataIds[] = $nextNews->id;
        

        return view('livewire.admin.app-news.container', [
            'newsDataRows'             => $newsDataRows,
            'newsDataIds'              => $newsDataIds,
            'form'                     => $this->form,
            'news_rows_count'          => $news_rows_count,
            'newsPublishedValueArray'  => $newsPublishedValueArray,
        ]);
    

在模板 resources/views/livewire/admin/app-news/container.blade.php 中:

<article class="admin_page_container">


<div class="card form-admin-news">
    
    <div class="card-body card-block">
    
        <div class="spinner-border" role="status" wire:loading>
            <span class="sr-only">Loading...</span>
        </div>
    
        ...
            <fieldset class="bordered text-muted p-2 m-2" x-data=" title: '$filters['title']', published: '$filters['published']'  ,
                publishedItems: <?php print  str_replace('"',"'",json_encode( $newsPublishedValueArray) ) ?>    ">
                <div> $filters:: var_dump($filters) </div>
                title::<div x-html="title"></div>
                published::<div x-html="published"></div>
                <legend class="bordered">Filters</legend>
                
                
                <dl class="block_2columns_md m-0 p-2">
                    <dt class="key_values_rows_label_13">
                        <label class="col-form-label" for="temp_filter_title">
                            By title
                        </label>
                    </dt>
                    <dd class="key_values_rows_value_13" >
                        <div class="content_with_right_button">
                            
                            <div
                                class="content_with_right_button_left_content"
                                wire:model.lazy="filters.title"
                            >
                                <input
                                    class="form-control admin_control_input"
                                    type="text"
                                    x-model="title"
                                    x-on:blur="$dispatch('input', title)"
                                    id="title"
                                >
                            </div>
                            <div class="content_with_right_button_right_button pl-2">
                                <button class="btn btn-outline-secondary nowrap_block" wire:click="makeSearch( )">
                                    !! $viewFuncs->showAppIcon('filter') !!Search
                                </button>
                            </div>
                        </div>
                    </dd>
                </dl>
                
                <dl class="block_2columns_md m-0 p-2">
                    <dt class="key_values_rows_label_13">
                        <label class="col-form-label" for="temp_filter_published">
                            By published
                        </label>
                    </dt>
                    <dd
                        class="key_values_rows_value_13"
                        wire:model.lazy="filters.published"
                    >
                        <select
                            x-model="published"
                            x-on:blur="$dispatch('select', published)"
                            id="published"
                            class="form-control editable_field admin_control_input"
                        >
                            <template x-for="nextPublishedItem in publishedItems">
                                <option :value="nextPublishedItem.key" x-text="nextPublishedItem.label"></option>
                            </template>
                        </select>
                        
                        @error('form.published')
                        <div class="validation_error"> clearValidationError($message,['form.'=>'']) </div> @enderror
                    </dd>
                </dl>
                
            </fieldset> <!-- Filters -->
        
        ...
        @endif -- @if($updateMode=='browse')--
        
    
        @endif -- @if($updateMode=='browse')--
            @if(count($newsDataRows) > 0)
                
                <div class="table-responsive table-wrapper-for-data-listing" x-data="selectedNewsIdsBoxXData()">
                    
                    <table>
                        ...
                    </table>
                </div> <!-- <div class="table-responsive table-wrapper-for-data-listing"> -->
            
            @endif -- @if(count($newsDataRows) > 0) --
        @endif -- @if($updateMode=='browse')  --
    </div> <!-- <div class="card-body card-block"> -->
    
    

</div> <!-- <div class="card"> -->
</article> <!-- page_content_container -->

哪种方式有效?

修改块 2:

我尝试使用 alpinejs2 的另一种方式:我尝试在这种情况下使用它,就像组件的公共 var 更改时一样: 单击“搜索”按钮时使用调度方法

<div class="card form-admin-facilities" x-data="adminFacilitiesComponent()">
    ...
    
    filter_name: $filter_name<br>
    ...
    temp_filter_name: <span x-html="temp_filter_name"></span><br>
    ...
    
    <fieldset class="bordered text-muted p-2 m-2">
        <legend class="bordered">Filters</legend>
        <div class="content_with_right_button" wire:model.lazy="filter_name">
            <div class="content_with_right_button_left_content" >
                <input
                    class="form-control admin_filter_input"
                    x-model="temp_filter_name"
                    
                    type="text"
                >
            </div>
            <div class="content_with_right_button_right_button pl-2" >
                <button class="btn btn-outline-secondary" @click="$dispatch('input', temp_filter_name)"  type="button">Search
                </button>
                <!-- In more complicated form can be several filter fields : text and select inputs -->
            </div>
        </div>
    
    </fieldset> <!-- Filters -->
    
    
    ...
    <script>
        function adminFacilitiesComponent() 
            return 
                temp_filter_name:'',

在组件中我定义了 public $filter_name var,它用于 render 方法:

   class Facilities extends Component
        
            public $form= [
                'name'=>'',
            'descr'=> '',
            'created_at'=> '',
            'is_reopen'       => false,
        ];

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

            public function render()
        
        \Log::info( '-1 render Facilities $this->filter_name ::' . print_r(  $this->filter_name, true  ) );
            $this->facility_rows_count = Facility
                ::getByName($this->filter_name, true)
        ->count();
            $backend_per_page = Settings::getValue('backend_per_page', CheckValueType::cvtInteger, 20);

            return view('livewire.admin.facilities.container', [
                'facilityDataRows' => Facility
            ::orderBy('created_at', 'desc')
        ->getByName($this->filter_name, true)
        ->paginate($backend_per_page),
            'facility_rows_count'=> $this->facility_rows_count
        ]);
        

但它不像我预期的那样工作:当这个输入失去焦点时在文本输入中输入值 表格再次呈现。我希望只有在单击“搜索”按钮时才会呈现表单 表单将使用新输入的值呈现。我不使用模糊事件进行文本输入和 不明白为什么当这个输入失去焦点时会呈现表单?

修改版块 3: 使用 x-ref= 我这样做:

<div class="content_with_right_button" wire:model.lazy="filter_name">
    <div class="content_with_right_button_left_content" >
        <input
            class="form-control admin_filter_input"
            x-model="temp_filter_name"
            x-ref="searched"
            type="text"
        >       1111111
    </div>
    <div class="content_with_right_button_right_button pl-2" >
        <button class="btn btn-outline-secondary nowrap_block" wire:click="makeSearch(this.$refs.searched)" type="button">
            Search
        </button>
    </div>
</div>

但我点击搜索按钮时出错:

VM1983:6 Uncaught TypeError: Cannot read property 'searched' of undefined
    at eval (eval at parseOutMethodAndParams (directive.js:55), <anonymous>:6:27)
    at _default.parseOutMethodAndParams (directive.js:55)

看起来无法使用 this.$refs。价值在

wire:click="makeSearch    .

我需要触发组件方法

public function makeSearch($search_value='')

并将输入的值发送到其中。 看起来我尝试的方式无效。 如果有有效的方法?

谢谢!

【问题讨论】:

查看修改后的 BLOCK 2 我仍在寻找决定。如何实施?谁有类似问题:请分享您的经验。 【参考方案1】:

为了使 livewire 忽略组件,只需将 wire:ignore 添加到已修改块 2 中组件的 div 中,然后在您的 dispatch 方法中,您可以编写单击按钮后发生的逻辑。

【讨论】:

能否请您详细说明>>>在您的调度方法中,您可以编写之后发生的逻辑 @mstdmstd 例如,如果您想要按钮单击时输入的值,那么您可以将x-ref=searched 分配给input 元素并通过'$refs.searched 或@987654326 获取它的值@当点击搜索按钮或任何你喜欢的时候 请您看一下修改后的 BLOCK 3【参考方案2】:

在您修改的块 2 中,您应该在 AlpineJS 组件的基本 div 中使用 wire:ignore。这将使 livewire 忽略该组件。

<div class="card form-admin-facilities" wire:ignore x-data="adminFacilitiesComponent()">

您的$dispatch() 应该在您单击按钮时处理设置值。

【讨论】:

能否提供一个链接到描述它的文档? 是的,wire:ignore 有帮助。您能否解释一下 $dispatch 中必须包含的内容(输入模糊?)?

以上是关于在编辑任何输入时呈现数据表单列表?的主要内容,如果未能解决你的问题,请参考以下文章

React Apollo GraphQL Mutation 返回 400(错误请求)

在另一个子表单中编辑数据时禁用子表单

Pandas数据框一旦部署到heroku(Django项目)后就无法按预期方式运行

将表数据映射到 asp .Net MVC 中的 ViewModel 列表

用于数据输入的表单集尝试创建重复记录导致错误

Django REST Framework:在列表响应中呈现表单元素