使用刀片组件在编辑视图的初始化时未正确检查检查按钮列表

问题描述 投票:0回答:2

在模型的编辑视图上,我有一个复选框列表,其元素应首先使用在创建实例时选择的对应值进行检查。 尽管我做了很多尝试,查阅了大量的网络文章和文档,但我无法达到这个目的。 我将编辑视图编码在与创建视图相同的文件中,有条件地渲染,第一个视图接收模型“Alquiler”的实例(位于“$alquiler”变量)和带有布尔值的“$editar”变量值设置为'true'就可以了。我正在使用 Alpine 将一些值传递给 Blade 组件。

那么,在我的主视图中,我有以下代码:

'caracteristicas.blade.php':

@php
    $condiciones = [];
    if($editar) {
        foreach($alquiler->servicios as $servicioOfrecido) {
            foreach($servicios as $servicio) {
                if($servicioOfrecido['id'] == $servicio['id']) {
                    debug_to_console($servicio);  //This is an aux function I've defined to log to the browser some PHP data when needed
                    array_push($condiciones, $servicioOfrecido['id']);
                }
            }
        }
    } 
    else {
        $condiciones[] = false;
    }
@endphp
...
@if($editar)
<form action="{{ route('partes.caracteristicas',$alquiler)}}" method="POST" id="caracteristicas">
@else
<form action="{{ route('partes.caracteristicas')}}" method="POST" id="caracteristicas">
@endif
@csrf
...

    <div x-data='{servicios:@json($servicios),condiciones:@json($condiciones)}' class="w-full">
      <ul class="whitespace-normal">
        <template x-for="(servicio,indice) in servicios" :key="indice">
          <x-check-boton x-bind::id='servicio.identificador' x-bind::texto='servicio.servicio' x-bind::valor='servicio.id' x-bind::condiciones='condiciones'></x-check-boton>
        </template>
      </ul>
    </div>

...

</form>

...

<script>
    console.log(@json($servicios));
    console.log(@json($condiciones));
</script>
...

我在刀片组件上的代码是这样的:

'check-boton.blade.php':

<li class="inline-block" {{$attributes}} x-data="{
          id:'',
          texto:'',
          valor:'',
          condicion:false,
          condiciones:[],
          
          init: function() {
              this.$nextTick( () => {
                 this.id = this.$el.attributes[':id'].value;
                 this.texto = this.$el.attributes[':texto'].value;
                 this.valor = this.$el.attributes[':valor'].value;
                 this.condiciones = this.$el.attributes[':condiciones'].value;e
                 this.condicion = this.condiciones.includes(this.valor);
              });
          }
        
        }">

<div class="flex" x-init='console.log(condiciones)'>
      <input type="checkbox" :id="id" name="servicios[]" :value="valor" class="peer hidden" x-model="condiciones" />
      <label :for="id" class="select-none cursor-pointer rounded-full border-[1px] border-gray-400
                 py-2 px-6 font-light text-gray-800 transition-colors duration-200 ease-in-out
                 peer-checked:bg-emerald-800 bg-transparent peer-checked:text-gray-50 peer-checked:border-none m-2"
                 x-text="texto"></label>
   </div>
</li>

那么,我在浏览器上得到了这个结果,这里还显示了在主视图中定义的用于调试目的的“console.log”结果,以及在 @php/@endphp 部分编码的日志记录:

Browser view

<div class="flex" x-init='console.log(condiciones)'>
处的结果是:

Component log

意味着组件未正确接收数组。

我尝试了一些其他的东西,比如在组件中做的事情:

<li class="inline-block" {{$attributes}} x-data="{
  id: '',
  texto: '',
  valor: '',
  condiciones: [],
  condicion: false,
  init: function() {
    this.$nextTick(() => {
      this.id = this.$el.attributes[':id'].value;
      this.texto = this.$el.attributes[':texto'].value;
      this.valor = this.$el.attributes[':valor'].value;
      this.condiciones = JSON.parse(this.$el.attributes[':condiciones'].value);
      this.condicion = this.condiciones.includes(parseInt(this.valor));
    });
  }
}">
 ....
</li>

但我正在控制台:

Uncaught SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at eval (eval at <anonymous> (app-7a4f3435.js:48:671), <anonymous>:14:31)
    at app-7a4f3435.js:48:3704
    at Ri (app-7a4f3435.js:48:3761)
    at app-7a4f3435.js:48:3666
eval @ VM1105:14
(anonymous) @ app-7a4f3435.js:48
Ri @ app-7a4f3435.js:48
(anonymous) @ app-7a4f3435.js:48
setTimeout (async)
(anonymous) @ app-7a4f3435.js:48

我还尝试在“x-model”中使用“condicion”而不是“condiciones”,如下所示:

<input type="checkbox" :id="id" name="servicios[]" :value="valor" class="peer hidden" x-model="condicion" />

知道我做错了什么吗?还需要更多信息吗?

如果有必要,我可以分享控制器的部分以及此问题的相关方法,以及通过tinker获得的一些“Alquiler”实例的内容,作为示例。

非常感谢!

莱安德罗

laravel laravel-blade alpine.js
2个回答
1
投票

一种解决方案是使用 PHP 将值列表传递给组件并使其内爆:

<x-check-boton x-bind::id='servicio.identificador'
               x-bind::texto='servicio.servicio'
               x-bind::valor='servicio.id'
               condiciones="{{ implode(';', $condiciones )}}"
>

然后在 init() 函数中可以通过分割字符串来提取值:

init: function() {

  this.$nextTick( () => {

     this.id = this.$el.attributes[':id'].value;
     this.texto = this.$el.attributes[':texto'].value;
     this.valor = this.$el.attributes[':valor'].value;

     this.condiciones = this.$el.attributes['condiciones'].value.split(';');

     this.condicion = this.condiciones.includes(this.valor);
  });
}

但是,由于子组件继承了父组件的属性,我认为更好的解决方案是从 check-boton 组件中完全删除 condiciones 属性,因此每个子组件都会引用父组件的 condiciones 列表:

<x-check-boton x-bind::id='servicio.identificador'
               x-bind::texto='servicio.servicio'
               x-bind::valor='servicio.id'
>

在子组件中:

<li class="inline-block" {{$attributes}} 
    x-data="{
       id:'',
       texto:'',
       valor:'',
       condicion:false,

       init: function() {
 
           this.$nextTick( () => {

               this.id = this.$el.attributes[':id'].value;
               this.texto = this.$el.attributes[':texto'].value;
               this.valor = this.$el.attributes[':valor'].value;
               this.condicion = this.condiciones.includes(this.valor);
           });
       }
        
}">

无论如何,x-模型必须设置为条件


0
投票

@皮波 尽管您建议的解决方案应该有效,但我终于可以像这样解决这个问题:

'caracteristecas.blade.php':

<div x-data='{servicios:@json($servicios),condiciones:@json($condiciones)}' class="w-full">
  <ul class="whitespace-normal">
    <template x-for="(servicio,indice) in servicios" :key="indice">
      <x-check-boton></x-check-boton>
    </template>
  </ul>
</div>

'check-boton.blade.php':

<li class="inline-block" x-data="{
          id:servicio.identificador,
          texto:servicio.servicio,
          valor:servicio.id}">

   <div class="flex">
      <input type="checkbox" :id="id" name="servicios[]" :value="valor" class="peer hidden" x-model="condiciones" />
      <label :for="id" class="select-none cursor-pointer rounded-full border-[1px] border-gray-400
                 py-2 px-6 font-light text-gray-800 transition-colors duration-200 ease-in-out
                 peer-checked:bg-emerald-800 bg-transparent peer-checked:text-gray-50 peer-checked:border-none m-2"
                 x-text="texto"></label>
   </div>
</li>

尽管有部分

 init: function() {
    this.$nextTick(() => {
    ...

适用于其他值,它不会在需要的时刻更新数组“condiciones[]”的值,导致当我在“x-model”上引用它时得到一个空数组

非常感谢!

莱安德罗

© www.soinside.com 2019 - 2024. All rights reserved.