【发布时间】:2013-06-04 14:10:25
【问题描述】:
我最近刚刚接到任务,在 5 天内为我们的 Magento 模板创建一个简单的产品配置器,您可以在其中选择一些属性,它会为您计算价格、淡入新图像并更改添加到购物车按钮到新产品。
在此之前,我没有 PHP 或 JQuery 方面的经验,只了解 Magento 的一些基础知识(以前从未做过自定义模块。)我唯一的编程背景是动作脚本 3 中的 OOP 游戏。
到目前为止,我的代码以某种方式工作。我有一些变量可以通过单击一些单选按钮来更改,并且这些变量通过 ajax 方法进行更新。作为 URL,我的块索引方法被调用,它只是加载和呈现我的布局。在我将返回的 HTML(这是我的整个块)添加到我的块中最外层 div 的父级之后。它可以工作,但我似乎无法找到一种方法来为更改设置动画,如果每次用户只更改一个选项时 ajax 重建整个块,它似乎有点慢。
有没有更优雅的方法来重新加载更改的部分、平滑地为更改设置动画并让我的模块记住所做的输入?
这里有源文件供下载:http://www.roflxd.de/doorconfig.zip
如果您需要查看网站本身,请给我留言 :)
提前致谢!
我的块 phtml:
<?php
$type = 'Simple';
$color = 'FFFFFF';
$size = '2500x1800';
if (isset($_POST['color'])) {
$color = "#" . $_POST['color'];
}
if (isset($_POST['type'])) {
$type = $_POST['type'];
}
if (isset($_POST['size'])) {
$size = $_POST['size'];
}
$currentStoreUrl = Mage::getBaseUrl();
$currentProduct = $this->getProduct($type,$color,$size);
$currentId = $currentProduct->getId();
$currentUrl = $currentProduct->getProductUrl();
$currentPrice = $this->getPrice($currentId);
$currentImgUrl = $this->getDoorBaseImgUrl($type, $size);
?>
<div id="door_wrapper" class="">
<div id="door_left_wrapper" class="mj-grid48">
<form id="testform">
<div id="door_colors">
<label id="FFFFFF">White<input type="radio" name="toggle" value="FFFFFF"></label>
<label id="000000">Black<input type="radio" name="toggle" value="000000"></label>
<label id="736D6C">Grey<input type="radio" name="toggle" value="736D6C"></label>
</div>
<div id="door_model" >
<?php print_r($_POST); ?>
<?php echo $type;?>
<?php echo $color;?>
<?php echo $size;?>
<br>
<?php echo $currentImgUrl;?>
</div>
<div id="door_size">
<select name="doorsizes">
</select>
</div>
<?php if ($currentProduct->isSaleable()): ?>
<button type="button">
<a href="<?php echo $currentStoreUrl . "checkout/cart/add?product=" . $currentId . "&qty=1";?>">
Test
</a>
</button>
<?php else: ?>
<button disabled>Out of Stock</button>
<?php endif;?>
</form>
</div>
<div id="door_right_wrapper" class="mj-grid48">
<div id="door_img">
<img src="<?php echo $currentImgUrl;?>">
</div>
<div id="result"></div>
</div>
</div>
<script type="text/javascript">
var $col = "000000";
var $type = "Advanced";
var $size = "3050x2150";
function ajaxUpdate()
{
$j.ajax({
url: "/doorconfig/ajax/index",
type: "POST",
data: {color : $col, type : $type, size : $size },
context: $j('#door_wrapper').parent(),
success: function(data)
{
$j(this).html(data).$(this).fadeIn(slow);
}
});
};
$j(document).ready(function()
{
$j("input[name=toggle]:radio").change(function ()
{
ajaxUpdate();
})
});
</script>
我的块 php:
<?php
class Geeklab_DoorConfig_Block_Doorconfig extends Mage_Core_Block_Template
{
public function getProduct($type,$color,$size)
{
//Get Product Collection
$collection = Mage::getModel('catalog/product')->getCollection();
//Select needed Attributes
$collection->addAttributeToSelect('doorconfig_enable');
$collection->addAttributeToSelect('doorconfig_color');
$collection->addAttributeToSelect('doorconfig_size');
$collection->addAttributeToSelect('doorconfig_type');
//Filter for Selected Product
$collection->addFieldToFilter('doorconfig_enable',
array(
'eq' => Mage::getResourceModel('catalog/product')
->getAttribute('doorconfig_enable')
->getSource()
->getOptionId('Yes')
)
);
$collection->addFieldToFilter('doorconfig_color',
array(
'eq' => Mage::getResourceModel('catalog/product')
->getAttribute('doorconfig_color')
->getSource()
->getOptionId($color)
)
);
$collection->addFieldToFilter('doorconfig_size',
array(
'eq' => Mage::getResourceModel('catalog/product')
->getAttribute('doorconfig_size')
->getSource()
->getOptionId($size)
)
);
$collection->addFieldToFilter('doorconfig_type',
array(
'eq' => Mage::getResourceModel('catalog/product')
->getAttribute('doorconfig_type')
->getSource()
->getOptionId($type)
)
);
$product = $collection->getFirstItem();
return $product;
}
public function getPrice($id)
{
$product = Mage::getModel('catalog/product')->load($id);
$_taxHelper = new Mage_Tax_Helper_Data;
$finalprice = $_taxHelper->getPrice($product, $product->getFinalPrice(), true);
$finalprice .= $this->getCurrency();
return $finalprice;
}
public function getCurrency()
{
return Mage::app()->getLocale()->currency(Mage::app()->getStore()->getCurrentCurrencyCode())->getSymbol();
}
public function getDoorImageDir()
{
return Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA) . 'wysiwyg/geeklab/doorconfig/';
}
public function getDoorBaseImgUrl($type, $size)
{
return $this->getDoorImageDir() . strtolower($size) . '_' . str_replace("\040", "\137", strtolower($type)) . '.png';
}
public function getDoorColorImgUrl($color, $size)
{
return $this->getDoorImageDir() . strtolower($size) . '_' . strtolower($color) . '.png';
}
}
?>
还有我的 AjaxController.php
<?php
class Geeklab_DoorConfig_AjaxController extends Mage_Core_Controller_Front_Action
{
public function indexAction ()
{
$this->loadLayout();
$this->renderLayout();
}
}
?>
【问题讨论】:
-
我正在逐个弄清楚理论。当前的行为非常有意义,因为我调用了在任何 ajax 事件上呈现布局的控制器,每次都重新加载 html。所以我需要第二个控制器动作或模型之类的东西,然后它会回答我的 ajax 调用并给我新的产品值。通过 jQuery 更改 DOM 并继续侦听更改后。 phtml 只会从 Magento 获取初始数据并初始化 configurator 的 select 和 color 字段。但问题仍然存在:我需要什么,模型、新控制器动作还是新控制器?
-
在另一个控制器操作中收集数据是一种好习惯吗?我可以从我的 Block.php 那里访问这些功能吗?这么多问题,请给我提示以正确的方式解决这个问题:)
-
我不得不在 Mage 中做同样的事情。一个团队成员编写了模块,我连接了 ajax。我使用 jQuery 发布到他在控制器中编写的操作方法。 Alan Storm's 站点是获取一些关于编写模块的好信息的好地方。希望这有助于为您指明正确的方向。
-
所以您还通过 2 种操作方法来实现它,一种用于构建布局,另一种用于在 ajax 请求上发回新产品数据?这意味着我应该可以在那里使用我的块方法 ^^ 你是使用 JSON 作为返回格式还是其他格式?我已经阅读了很多 Alan Storms 的文章,这让我更容易获得基础知识 :)
-
阅读此QUESTION 我认为可以在我的新控制器操作中进行变量设置,但随后阅读 Alan Storms 的答案,这似乎不是一个好习惯。所以我想到我需要第二个控制器 Action 来实例化数据操作的模型。没有找到任何指南,没有使用资源模型进行数据库访问:/我只想从 Magento 读取简单数据并将其作为 JSON 发送回我的块。