Magento 2中的收藏历史吗?


25

我知道目前Magento 2(2.1.2)中的许多代码或多或少是从Magento 1移植的,并且将来很多代码将被等效代码替代。在这方面,我想知道Magento 2系列的未来。

让我解释:

Magento 1:

在Magento 1中,我们习惯于获得这样的集合:

$products = Mage::getModel('catalog/product')->getCollection();

然后,我们可以对集合应用过滤器和其他操作:

$products->addAttributeToFilter('price', ['gteq' => 10]);
$products->addFieldToFilter('created_at', ['lt' => '2016-10-10']);
$products->setPageSize(10);
// ... etc ...

最后但并非最不重要的一点是,我们的集合将返回模型:

foreach ($products as $product) {
    echo get_class($product); // Mage_Catalog_Model_Product
}

Magento 2:

Magento添加了许多新的抽象层,实现了一种更可靠的工作方式。这意味着当我们想要实体列表时,我们从存储库中请求它:

$productResults = $this->productRepository->getList($searchCriteria);

如果我们要应用过滤器,我们使用的一个组合SearchCriteriaBuilder,在FilterGroupBuilder中,FilterBuilderSortOrderBuilder

$this->searchCriteriaBuilder->addSortOrder(
    $this->sortOrderBuilder
        ->setField('created_at')
        ->setAscendingDirection()
        ->create()
);
$priceFilter = $this->filterBuilder
    ->setField('price')
    ->setValue(10)
    ->setConditionType('gteq')
    ->create();
$createdAtFilter = $this->filterBuilder
    ->setField('created_at')
    ->setValue('2016-10-10')
    ->setConditionType('lt')
    ->create();
$filterGroups = [
    $this->filterGroupBuilder->addFilter($priceFilter)->create(),
    $this->filterGroupBuilder->addFilter($createdAtFilter)->create()
];

而且,如果我们要遍历结果,则可以得到数据模型,而不是实际的(继承的)模型:

foreach ($productResults->getItems() as $product) {
    echo get_class($product); // \Magento\Catalog\Model\Data\Product
}

这种抽象遵循SOLID原则,并包含“继承之上的组成”原则。否则将在集合上执行的任何“外来”操作(例如示例连接)都在存储库内部进行,这也使得在模块外部使用起来更加容易。

问题:

所有这些使我感到奇怪:在整个存储库/数据模型方法中,Magento 2的未来是否有收集空间?集合只能在模块内部内部使用,而不能在模块外部使用吗?还是不赞成使用实体管理器?

当前,如果您想使用数据模型,则仍必须创建一个继承模型(继承自\Magento\Framework\Model\AbstractModel),以使集合正常工作(因为Magento\Framework\Data\Collection::setItemObjectClass要求模型从扩展Magento\Framework\DataObject)。而且您需要进行收集才能在存储库中进行过滤。但是再说一次,在存储库中,您必须将(常规)模型“转换”为数据模型。

还是我们必须像Order Repository那样实现它,在其中getList()返回的实例Magento\Sales\Api\Data\OrderSearchResultInterface,但是在水下搜索结果仅是实现此接口的常规集合。有趣的事实:搜索结果表明它将返回一个数据模型(Magento\Sales\Api\Data\OrderInterface[])数组,但是如果您分析代码,getItems()则会执行Magento\Framework\Data\Collection::getItems()该代码,而不是返回数据模型,而是返回订单模型(由设置Magento\Sales\Model\ResourceModel\Order\Collection::_construct())。对于“组成而不是继承”而言,就这么多。

关于Magento 2的正确方法有很多问题。同样,有100种方法可以做相同的事情,但是什么是Magento Way?还是我在这里完全走错了路?


2
在这里询问真实的问题+1。我真的很想在这里回答核心开发人员问题
Marius

我相信该计划是要逐步淘汰馆藏的。但是,正如您注意到的那样,这几乎还没有完成,而且有许多区域似乎处于重构的各种状态(具有稳定的api,如Magento \ Sales \ Api \ Data \ OrderSearchResultInterface,允许Magento替换稍后更容易发生)。getList的各种实现还没有像我们目前对集合所做的那样有能力,这无济于事。您在声明的收益周围发现的不一致之处可能值得在github上解决。
克里斯托夫在Fooman,2013年

Answers:


16

集合现在不被弃用。尽管某些模块已经公开了Service Contract API,但其他模块仍然只公开了Model / Collection API。

该计划是:

  1. 以更好的@api覆盖率反映当前状态:使用@api注释某些模块中的抽象集合和特定集合
  2. 改进持久性框架,以轻松创建服务合同,而无需依赖于基于继承的API:集合,模型,资源模型
  3. 弃用抽象集合以不促进基于集合的服务合同的实现
  4. 使用Service Contract API逐步发布模块的较新版本

因此,集合将在某个时候被弃用,但是现在它们是Magento 2 API之一。

至于服务合同的实现,-模型和集合是在Magento <= 2.1中实现它们的唯一便捷方法。服务合同只是接口。它们的实现不是公共API的一部分,以后可能会更改。


1
感谢您的回答。那么,您对创建新模块的开发人员有何建议?我当前的策略是创建(在水下)仍然使用集合的服务合同,因为a)使过滤变得容易,并且b)实体管理器仍处于实验性/未记录的状态。在某些时候,内部工作方式可以用任何其他东西代替,但是接口保持不变。但是,如果我正确理解了您的答案,那现在是正确的方法吗?
吉尔·伯克斯

正确。我修改了答案以反映这一点。
安东·克里尔

1
考虑到上述情况,实现需要无法通过服务合同获取数据的功能的正确方法是什么?例如,如果模块A要求所有按付款方式过滤的订单。
斯捷潘
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.