【问题标题】:Overriding/Extending the Magento core javascript files覆盖/扩展 Magento 核心 javascript 文件
【发布时间】:2012-08-10 02:13:39
【问题描述】:

最近几天,由于一些客户的投诉以及与我们的营销人员的讨论,我收到了更改可配置产品选项的默认行为的请求。他们要求我从选项下拉列表中删除 + $xx.xx,因为它会使客户/访客感到困惑,并且只留下可用选项而不显示价格变化。从他们的角度来看,这很公平,但从开发人员的角度来看,我认为这有点棘手。该站点运行 Magento CE 1.6.2,我们需要覆盖/更改的文件是 /public_html/js/varien/configurable.js。我们需要更改其中的 getOptionLabel 函数,使其不显示价格变化。 所以我的问题是:更改此文件而不触及核心 javascript 文件的正确 Magento 方法是什么? 提前致谢。

【问题讨论】:

  • javascript 不支持覆盖。但看到stackoverflow.com/questions/5409428/…
  • @Guerra 你确定原型有办法很好地包装()东西
  • IMO 这是一个模拟 OOP 覆盖的 hack,但工作正常

标签: javascript magento magento-1.6


【解决方案1】:

请参阅原型手册http://prototypejs.org/doc/latest/language/Function/prototype/wrap/ 中的此内容,您可以包装任何对象方法,甚至在需要时调用“父级”,这是一个伪示例:

//where Product.Config is the object/class you need to "override"
Product.Config.prototype.getOptionLabel  = Product.Config.prototype.getOptionLabel.wrap(function(parentMethod){
    //replace the original method here with your own stuff
    //or call parentMethod(); if conditions don't match
});

【讨论】:

  • 非常感谢 Anton 的提示。我会在早上玩它,看看它的表现如何。
  • 对于 Magento 1.7 这有效: Product.Config.prototype.getOptionLabel = Product.Config.prototype.getOptionLabel.wrap
  • 猜这取决于方法的命名方式
  • 我试图找出放置覆盖核心文件的 JS 文件的最佳位置。在我的例子中,它是 js/prototype/validation.js,我在整个 Mage 中看到可能有 5 到 10 个对该 .js 文件的不同引用。并不是所有的都是布局xml。
  • 您可以添加到原始文件之后加载的任何文件。我会添加自己的文件并将其放在那里。
【解决方案2】:

只是为了添加到@anton-s 的绝对正确答案,您还可以进行“完整”类重写:

// Create the original class
var ClassA = Class.create();
ClassA.prototype = {
    initialize: function(config) {
        this.config = config;
    },
    test: function(msg) {
        console.log('Hi from class A with message ' + msg);
    }
};

// Create new class extending the original class
var ClassB = Class.create(ClassA, {
    // $super is a reference to the original method
    test: function($super, msg) {
        console.log('Hi from class B');
        console.log('this.config is accessible in class B: ' + this.config);
        $super(msg + ' ...')
    }
});


// To make the extend an override, you can do this:
ClassA = ClassB;
// ClassA now is ClassB overriding the original ClassA
var a = new ClassA('some config data');
a.test('Call A 1');

由于所有这些仅适用于原型类,而不适用于已实例化的对象,因此我也将加入这个 hack,这几乎也是 wrap() 所做的:

// Overriding a method of an already instantiated object
// There are many ways to do this more elegantly thanks to the amazing JS scoping magic
a.origTest = a.test;
a.test = function(msg) {
    console.log('Hi from the patched method');
    this.origTest(msg);
}
a.test('Call A 2');

请记住,wrap() 方法更好,也可以用于类定义或具体实例。

// Wrap method of concrete instance
spConfig.getOptionLabel = spConfig.getOptionLabel.wrap(function(parentMethod, option, price) {
    return parentMethod(option, price);
});

// Wrap method of class declaration
Product.Config.prototype.getOptionLabel = Product.Config.prototype.getOptionLabel.wrap(function(parentMethod, option, price) {
    return parentMethod(option, price);
});

【讨论】:

  • 非常感谢 Vinai 和 Anton S 的宝贵提示。我们已经更改了我们的临时 js hack,现在它以正确的 Magento 方式完成。你是石头!
  • @MilenPetrov 接受有助于您改善搜索类似内容的其他人的 SO 体验的答案
  • @Anton S - 真的很抱歉我忘了这样做
【解决方案3】:

如何在 Magento 1.9 EE 中覆盖 \js\varien\configurable.js 并添加新的数据属性

创建文件\js\jsoverride\configurable.js:

    Product.Config.prototype.reloadOptionLabels = Product.Config.prototype.reloadOptionLabels.wrap(function (parentMethod, element) {
    var selectedPrice;
    if (element.options[element.selectedIndex].config && !this.config.stablePrices) {
        selectedPrice = parseFloat(element.options[element.selectedIndex].config.price);
    } else {
        selectedPrice = 0;
    }
    for (var i = 0; i < element.options.length; i++) {
        if (element.options[i].config) {
            element.options[i].text = this.getOptionLabel(element.options[i].config, element.options[i].config.price - selectedPrice);
            element.options[i].setAttribute('data-in-stock', element.options[i].config.in_stock);
        }
    }
});

创建或使用文件:\app\design\frontend\enterprise\YOUR_THEME\layout\local.xml 并添加下一行:

<?xml version="1.0"?>
<layout version="0.1.0">
  <catalog_product_view>
    <reference name="head">
      <action method="addJs"><script>jsoverride/configurable.js</script></action>
    </reference>
  </catalog_product_view>
</layout>

注意,将数据填充到文件中的 element.options[i].config.in_stock

app\design\frontend\enterprise\YOUR_THEME\template\catalog\product\view\type\options\configurable.phtml

下一行

var spConfig = new Product.Config(UPDATED JSON WITH NEW ATTRIBUTE);

【讨论】:

    猜你喜欢
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-16
    • 2015-06-16
    相关资源
    最近更新 更多