14

ここ数日、一部の顧客から苦情があり、マーケティング担当者と話し合った結果、構成可能な製品オプションのデフォルトの動作を変更するようにというリクエストがありました。顧客/訪問者を混乱させるため、オプションのドロップダウンから + $xx.xx を削除し、価格の変更を表示せずに利用可能なオプションをそのままにしておくように依頼されました。彼らの観点からは十分ですが、開発者の観点からは少しトリッキーだと思います。サイトは Magento CE 1.6.2 を実行しており、オーバーライド/変更する必要があるファイルは /public_html/js/varien/configurable.js です。価格の変化が表示されないように、getOptionLabel 関数を変更する必要があります。だから私の質問は、このファイルを変更し、コアのjavascriptファイルに触れない正しいMagentoの方法は何ですか? 前もって感謝します。

4

3 に答える 3

30

プロトタイプ マニュアル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
});
于 2012-08-13T20:35:02.773 に答える
26

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

これはすべて、すでにインスタンス化されたオブジェクトではなく、プロトタイプ クラスでのみ機能するため、このハックも投入します。

// 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);
});
于 2012-08-14T06:22:54.047 に答える