上节我们只是建立了小插件,但是数据是模拟的,我们希望将数据存储起来,那么我们就需要通过关联表将数据与视频表关联并保存,下面我们打开Builder,创建演员表
【database】
【Models】
【Models】——【Forms】
【Models】——【Lists】
【Models】——【Backend Menu】
【Models】——【Controllers】
【Models】——【Backend Menu】设置URL
刷新页面,然后选择视频,可以进入演员编辑页面:
添加演员数据:
因为我们前期使用了repeater字段存储演员信息,这次我们将用数据库存储演员信息。所以需要将演员这个字段从视频表中删除。
下面我们将要建立一个中间表格作为视频和演员的中间表实现多对多的关联
接下来就需要建立视频和演员表的多对多的关系、
File:plugins/raiseinfo/movies/models/Movie.php
public $belongsToMany = [ 'genres' => [ 'Raiseinfo\Movies\Models\Genre', // 模型 'table' => 'raiseinfo_movies_movies_genres', // 中间表 'order' => 'genre_title' ], 'actors' => [ 'Raiseinfo\Movies\Models\Actor', // 模型 'table' => 'raiseinfo_movies_actors_movies', // 中间表 'order' => 'name' ] ];
File:plugins/raiseinfo/movies/models/Actor.php
public $belongsToMany = [ 'movies' => [ 'Raiseinfo\Movies\Models\Movie', // 模型 'table' => 'raiseinfo_movies_actors_movies', // 中间表 'order' => 'name' ] ];
通过上述的代码修改,就实现了Movies和Actors表的多对多的关联关系。
下面修改部件,实现数据保存
首先需要准备数据变量,给小部件使用
File:plugins/raiseinfo/movies/formwidgets/Actorbox.php
public function render() { $this->prepareVars(); dump($this->vars['actors']); return $this->makePartial('widget'); } public function prepareVars() { $this->vars['id'] = $this->model->id; $this->vars['actors'] = Actor::all()->lists('name','id'); }
接下来就可以修改插件了pluginsraiseinfomoviesformwidgetsactorboxpartials_widget.htm
.select2-container { width: 100% !important; display: block; } $value): ?> "> $(document).on('render',function () { $('.s2').select2({ placeholder: 'Add Actors', tags: true }) });
现在显示了演员表中的所有演员的名,但是,没有显示所有演员的姓。我们需要在Actor中做适当修改:plugins/raiseinfo/movies/models/Actor.php
/** * 访问器的命名对应的就是full_name * @return string */ public function getFullNameAttribute() { return $this->name." ".$this->lastname; }
File:plugins/raiseinfo/movies/formwidgets/Actorbox.php
public function prepareVars() { $this->vars['id'] = $this->model->id; $this->vars['actors'] = Actor::all()->lists('full_name','id'); }
这样显示的就会有姓和名了。
为了在前端页面上显示演员的信息,我们需要对select进行设置
File:plugins/raiseinfo/movies/formwidgets/Actorbox.php
public function prepareVars() { $this->vars['id'] = $this->model->id; $this->vars['actors'] = Actor::all()->lists('full_name','id'); $this->vars['name'] = $this->formField->getName().'[]'; }
记得添加引用Actor的语句在页面头部
use Raiseinfo\Movies\Models\Actor;
File:plugins/raiseinfo/movies/formwidgets/actorbox/partials/_widget.htm
<select class="s2" name="<?php echo $name ?>" multiple> <?php foreach($actors as $key => $value): ?> <option value="<?php echo $key ?>"><?php echo $value ?></option> <?php endforeach; ?> </select>
File:themes/raiseinfo/pages/movie-single.htm
<h3>演员</h3> {% for actor in record.actors %} {{ actor.name }} {{ actor.lastname }} {% endfor %}
刷新前端页面:
通过上面的测试,我们已经知道,演员信息已经存储到数据库了,在前端也显示出来。下面我们刷新后台页面,打开编辑视频信息。我们发现存储的演员信息并没有显示在Select中。
这是因为我们没有设置显示选定的值。
File:plugins/raiseinfo/movies/formwidgets/Actorbox.php
public function prepareVars() { $this->vars['id'] = $this->model->id; $this->vars['actors'] = Actor::all()->lists('full_name','id'); $this->vars['name'] = $this->formField->getName().'[]'; // 下面一行 $this->vars['selectedValues'] = $this->getLoadValue(); }
File:plugins/raiseinfo/movies/formwidgets/actorbox/partials/_widget.htm
<select class="s2" name="<?php echo $name ?>" multiple> <?php foreach($actors as $key => $value): ?> <option value="<?php echo $key ?>" <!-- 下面这一行 --> <?php echo in_array($key,$selectedValues) ? 'selected="selected"' : '' ?> > <?php echo $value ?> </option> <?php endforeach; ?> </select>
好的,现在我们已经可以显示已选择的演员了,但是,我们如果编辑一个没有设置演员的视频:
解决问题的办法是:
File:plugins/raiseinfo/movies/formwidgets/Actorbox.php
public function prepareVars() { $this->vars['id'] = $this->model->id; $this->vars['actors'] = Actor::all()->lists('full_name','id'); $this->vars['name'] = $this->formField->getName().'[]'; if(!empty($this->getLoadValue())){ $this->vars['selectedValues'] = $this->getLoadValue(); }else{ $this->vars['selectedValues'] = []; } }