Переопределение/расширение основных файлов javascript Magento

В последние дни в результате того, что некоторые клиенты жалуются и обсуждают с нашими партнерами по маркетингу, у меня есть запрос изменить поведение по умолчанию для настраиваемых параметров продуктов. Они попросили меня удалить + $xx.xx из раскрывающегося списка опций, так как это запутывает клиентов/посетителей и просто оставляют доступные параметры без отображения изменения цены. Достаточно справедливо с их точки зрения, но это немного сложно с точки зрения разработчиков, я думаю. На сайте работает Magento CE 1.6.2, а файл, который нам нужно переопределить/изменить, -/public_html/js/varien/configurable.js. Нам нужно изменить функцию getOptionLabel в нем, чтобы она не отображала изменение цены. Поэтому мой вопрос: какой правильный способ Magento изменить этот файл и не касаться основного файла javascript? Спасибо заранее.

Ответ 1

Смотрите это из прототипа manual 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
});

Ответ 2

Просто чтобы добавить к абсолютно корректному ответу @anton, вы также можете выполнить "полный" перезапуск класса:

// 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');

Так как все это работает только на прототипных классах, а не на уже созданных объектах, я также буду использовать этот хак, что в значительной степени связано с 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);
});

Ответ 3

Как переопределить \js\varien\configurable.js в Magento 1.9 EE и добавить новый атрибут данных

Создайте файл \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);