我安装了SkeletonApplication并从ZF2 Docs创建了默认的相册模块。 http://framework.zend.com/manual/2.2/en/user-guide/modules.html
之后,我创建了类别模块的类别模块。 以下是它们的字段:category_id和category_name
然后为专辑表添加额外字段:cat_id 如您所知,我正在尝试对专辑进行分类。
然后我将此代码添加到AlbumForm.php文件中,用于字段集从selectbox中选择cat_id
$this->add(array(
'type' => 'Zend\Form\Element\Select',
'name' => 'cat_id',
'options' => array(
'value_options' => $selectOptions,
'label' => 'Category',
),
));
现在,我怎样才能将category_name和category_id从另一个类别模块转到专辑模块?
答案 0 :(得分:2)
如果我们能够看到您的类别模块文件的代码,那将是件好事。
首先,您应该考虑是否确实需要一个新的模块,因为它可能应该在同一个模块中,只需要创建新的模型类和新视图(如果有的话)。无论如何,在这一点上它并不重要。
如果你在我的Album模块中使用SkeletonApplication,在Module.php中你有这个代码:
public function getServiceConfig()
{
return array(
'factories' => array(
'Album\Model\AlbumTable' => function($sm) {
$tableGateway = $sm->get('AlbumTableGateway');
$table = new AlbumTable($tableGateway);
return $table;
},
'AlbumTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Album());
return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
然后可能你为类别表创建了类似的东西,比如
public function getServiceConfig()
{
return array(
'factories' => array(
'Category\Model\CategoryTable' => function($sm) {
$tableGateway = $sm->get('CategoryTableGateway');
$table = new CategoryTable($tableGateway);
return $table;
},
'CategoryTableGateway' => function ($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Album());
return new TableGateway('category', $dbAdapter, null, $resultSetPrototype);
},
),
);
}
让我知道它是否有很大不同。
由于所有配置都已合并,因此无论您是否在其他模块中,您的服务管理器都可以在您的控制器中找到Category \ Model \ CategoryTable。
所以,你必须修改你的AlbumForm类,所以例如在构造函数中你可以传递依赖项,例如servicemanager或'Category \ Model \ CategoryTable',所以当你需要检索$ selectOptions列表时,你可以访问它以进行任何查询。
此外,您可以从samsonasik查看更精彩的解决方案,但可能更难理解。
而且,您可以从jamescarr查看此blog post和code,以达到您所需要的相同水平。 这很容易理解,这是一个很好的解决方案。
答案 1 :(得分:2)
事实上,您不必为您的类别模型创建新模块 =>把它放在你的相册模块中:))
繁殖模块不是一个好主意......每个表一个太多了:D
在我看到你的先例aswer之后你仍然遇到麻烦时,我编写并评论了所有代码,以便你能更好地理解:)
ServiceManager工厂是一个非常重要的概念,非常了解!
因此,您首先必须在module.php文件中进行出厂配置:
namespace Album;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;
use Album\Model\Album;
use Album\Model\AlbumTable;
use Album\Model\Category;
use Album\Model\CategoryTable;
class Module
{
public function getServiceConfig()
{
return array (
'factories' => array(
//here already the AlbumTable config
// here begin the categoryTable factory
'Album\Model\CategoryTable' => function($sm)
{
//get the tableGateway just below in his own factory
$tableGateway = $sm->get('CategoryTableGateway');
//inject the tableGateway in the Table
$table = new CategoryTable($tableGateway);
return $table;
},
//here is the tableGateway Factory for the category
'CategoryTableGateway' => function($sm)
{
//get adapter to donnect dataBase
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
// create a resultSet
$resultSetPrototype = new ResultSet();
//define the prototype of the resultSet
// => what object will be cloned to get the results
$resultSetPrototype->setArrayObjectPrototype(new Category());
//here you define your database table (category)
//when you return the tableGateway to the CategoryTable factory
return new TableGateway('category', $dbAdapter, null, $resultSetPrototype);
},
),
),
}
}
在module / Album / src / Album / Model:
中创建Category.php文件namespace Album\Model;
class Category
{
public $id;
public $name;
public function exchangeArray(){
$this->id = (isset($data['id'])) ? $data['id'] : null;
$this->name = (isset($data['name'])) ? $data['name'] : null;
}
}
在同一文件夹中创建您的CategoryTable.php文件(Select输入只需要fetchAll()方法,您只需要所有类别的列表)
namespace Album\Model;
use Zend\Db\TableGateway\TableGateway;
use Album\Model\Category;
class CategoryTable
{
protected $tableGateway;
public function __construct(TableGateway $tableGateway)
{
$this->tableGateway = $tableGateway;
}
public function fetchAll()
{
$resultSet = $this->tableGateway->select();
return $resultSet;
}
public function getCategory($id){
// ...
}
public function saveCategory(Category $category)
{
// ...
}
public function deleteCategory($id)
{
// ...
}
}
不要忘记在AlbumTable :: saveAlbum()方法中添加新的cat_id字段;)
在相册/表单文件夹
中创建表单及其过滤器namespace Album\Form;
class AlbumForm{
public function __construct($cat_options){
$this->add(array(
'name' => 'id',
'required' => false,
'type' => 'hidden',
));
$this->add(array(
'name' => 'cat_id',
'required' => true,
'type' => 'Select',
'options' => array(
'value_options' => $cat_options,
'label' => 'Category',
)
'attributes' => array(
'value' => 3, // to select a default value
)
));
//and the rest of the form
$this->add(array(
'name' => 'submit',
'type' => 'Submit',
'attributes' => array(
'id' => 'submitbutton',
'value' => 'Go',
),
));
}
}
请注意,我将过滤器放在特定类中,位于Form所在的同一名称空间中。 =>当模块中有很多表单和模型时,更容易找到... =>我更喜欢它,所以我推荐它:D =>您可以为同一个模型提供多个表单,例如registration,login和resetPassword表单,例如,所有表单都用于同一个User类
namespace Album\Form;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
class AlbumFilter implements InputFilterAwareInterface
{
protected $inputFilter;
public function setInputFilter(InputFilterInterface $inputFilter)
{
throw new \Exception("Not used");
}
public function getInputFilter()
{
if(!$this->inputFilter)
{
$inputFilter = new InputFilter();
$inputFilter->add(array(
'name' => 'id',
'required' => false,
'filters' => array(
array('name' => 'Int'),
),
));
$inputFilter->add(array(
'name' => 'cat_id',
'required' => true,
'filters' => array(
array('name' => 'Int'),
),
));
$inputFilter->add(array(
'name' => 'artist',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 45,
),
),
),
));
$inputFilter->add(array(
'name' => 'title',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 45,
),
),
),
));
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
}
现在所有内容都配置好了,让控制器:)
namespace Album\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Album\Model\Album;
use Album\Form\AlbumForm;
class MyControler extends AbstractActionController
{
private $CategoryTable;
public function getAlbumsTable(){
if(!$this->Album){
// get AlbumTable from the ServiceLocator factory (defined in Module.php)
$this->Album = $this->getServiceLocator()
->get('Album\Model\AlbumTable');
}
}
public function getCategoryTable(){
if(!$this->CategoryTable){
$this->CategoryTable = $this->getServiceLocator()
->get('Album\Model\CategoryTable');
}
}
public function addAction(){
//get the categories from the database
$categories = $this->getCategoryTable()->fetchall();
//make an array from the resultSet
// you can do it as well in your controller
//or in your form class like I did in my yersterday's answer
$cat_options = array();
foreach ($categories as $category) {
$cat_options[$category->id]=$category->name;
}
//create your form with category list as parameter
$form = new AlbumForm($cat_options);
//here I recomend to create a specific class for you filters
// and not put it in your Album class as describe in the zf tutorial
// => so you can have several forms using the same Model
// and it is more easy to find on the form folder ;)
$filter = new AlbumFilter();
//inject InputFilter in your form
$form->setInputFilter($filter->getInputFilter());
//inject data in form
$form->setData($request->getPost());
//check the form validity (data vs filters)
if($form->isValid()){
//create a new album
$album = new Album();
//hydrate your Album
$album->exchangeArray($form->getData());
//ask the albumsTable to save album in the database
$this->albumsTable->saveAlbum($album);
//here you can redirect to the Album list
$this->redirect()->toRoute('Album');
}
//call the viewModel if first time you see the page
// or if validation errors of the form.
return array('form' =>$form);
}
}
然后你只需要发表你的看法......我不会在这里犯下这个代码;)
如果您仍然需要在应用程序中创建多个模块,可以使用工厂调用控制器中的任何objectTable和getobjectTable()方法:正如Carlos所说,getServiceConfig()数组都合并为一个,所以您可以从应用程序的任何位置获取任何表:)