【问题标题】:Laravel nova, custom resource tool not appears in edit modeLaravel nova,自定义资源工具不出现在编辑模式下
【发布时间】:2019-02-11 14:20:19
【问题描述】:

我有一个自定义资源工具在资源的视图面板中工作正常,但是当我进入编辑模式时它不会出现。有什么我应该添加到组件或 Nova 配置中以在编辑模式下启用组件的吗?

User.php中的代码

public function fields(Request $request)
{

    return [
        ID::make()->sortable(),

        Text::make('First name', 'firstName')
            ->sortable()
            ->rules('required', 'max:255'),

        Text::make('Last name', 'lastName')
            ->sortable()
            ->rules('required', 'max:255'),

        Text::make('Email')
            ->sortable()
            ->rules('required', 'email', 'max:254')
            ->creationRules('unique:users,email')
            ->updateRules('unique:users,email,{{resourceId}}'),

        Password::make('Password')
            ->onlyOnForms()
            ->creationRules('required', 'string', 'min:6')
            ->updateRules('nullable', 'string', 'min:6'),

        YesNovaUserPermissions::make(),
    ];
}

用户视图:

用户编辑:

【问题讨论】:

    标签: laravel laravel-nova


    【解决方案1】:

    Nova 似乎不允许您使用自定义资源获得此功能,但您可以使用 custom field。您基本上创建了一个模型上并不真正存在的“虚拟”字段,并在模型上使用mutator 来覆盖默认的模型保存功能。

    按照上面的文档,您可以构建一个 Vue 组件,该组件将出现在资源编辑表单本身中,类似于我使用下图所示的标签选择器所做的。

    代码:

    <template>
      <default-field :field="field" :errors="errors" :show-help-text="showHelpText">
    
      <label for="tag" class="inline-block text-80 pt-2 leading-tight">Tag</label>
    
      <template slot="field">
        <div id="multitag-flex-holder">
          <div id="multitag-search-holder" class="w-1/2">
            <div class="search-holder">
              <label>Search Categories</label>
              <input type="text" v-model="searchString" @focus="isSearching = true" @blur="isSearching = false" style="border:2px solid #000"/>
    
              <div class="found-tags" v-if="isSearching">
                <div v-for="(tag, i) in foundTags" @mousedown="addToSelected(tag)" :key="i">{{tag.name}}</div>
              </div>
            </div>
          </div>
    
          <div class="select-tags-holder w-1/2">
            <div class="selected-tags">
              <div v-for="(tag, i) in selectedTags" :key="'A'+i" @click="removeTag(tag)">{{tag.name}}   X</div>
            </div>
          </div>
        </div>
      </template>
    
      </default-field>
    </template>
    
    <script>
    import { FormField, HandlesValidationErrors } from 'laravel-nova'
    
    export default {
      mixins: [FormField, HandlesValidationErrors],
    
      props: ['resourceName', 'resourceId', 'field'],
    
      data: function () {
        return {
          selectedTags:[],
          isSearching:false,
          searchString:''
        }
      },
    
      mounted(){
        console.log(this.field)
        this.field.value.forEach((tag)=>{
          this.addToSelected(tag)
        })
        formData.append('whereType', 'Tag');
      },
    
      computed: {
        // a computed getter
        foundTags() {
          // `this` points to the vm instance
    
            return this.field.tags.filter((tag) => {
              if(tag.name.search(new RegExp(this.searchString, "i")) >= 0){
                if(this.selectedTagNames.indexOf(tag.name) == -1){
                  return tag;
                }
              };
            })
    
        },
        selectedTagNames(){
          var selNames = this.selectedTags.map((tag) => {
              return tag.name;
          })
          return selNames;
        }
      },
    
      methods: {
        /*
         * Set the initial, internal value for the field.
         */
        setInitialValue() {
          this.value = this.field.value || ''
        },
    
        removeTag(tag){
          var index = this.selectedTags.indexOf(tag);
          if (index > -1) {
            this.selectedTags.splice(index, 1);
          }
        },
    
        addToSelected(tag){
          this.selectedTags.push(tag)
        },
    
        /**
         * Fill the given FormData object with the field's internal value.
         */
        fill(formData) {
          var tagIdArray = []
          this.selectedTags.forEach((tag)=>{
            tagIdArray.push(tag.id)
          })
          formData.append(this.field.attribute, tagIdArray)
        },
      },
    }
    
    </script>
    

    然后,您可以覆盖模型中保存功能的工作方式以适应“虚拟”字段。请注意下面,而不是直接在 mutator 上同步标签,这将在大多数情况下工作,具体取决于您的数据结构,我必须将标签传递给模型上的“已保存”事件以适应创建新记录和关联的记录 ID 尚不可用,因此无法同步多对多关系。

    public function setTagsAttribute($value)
    {
    
        $tags = explode(",", $value);
        $this->tempTags = $tags;
        unset($this->tags);
    }
    
    protected static function booted()
    {
        static::saved(function ($article) {
            $article->tags()->sync($article->tempTags);
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-02
      • 1970-01-01
      • 2022-10-19
      • 2020-02-11
      • 2019-08-16
      • 2021-10-21
      • 2019-02-21
      • 1970-01-01
      相关资源
      最近更新 更多