2012-08-13 174 views
14

由於某些客戶抱怨並與我們的營銷人員進行討論,最後幾天我收到了更改可配置產品選項默認行爲的請求。他們要求我從選項下拉菜單中刪除+ $ xx.xx,因爲它會讓客戶/訪客感到困惑,並且只保留可用選項而不顯示價格變化。從他們的觀點來看,這很公平,但從開發人員的角度來看,我認爲這有點棘手。該網站正在運行Magento CE 1.6.2,我們需要覆蓋/更改的文件是/public_html/js/varien/configurable.js。我們需要更改其中的getOptionLabel函數,以便它不顯示價格變化。 所以我的問題是:什麼是正確的Magento方式來改變這個文件,而不是觸摸核心JavaScript文件? 在此先感謝。覆蓋/擴展Magento核心JavaScript文件

+0

javascript不支持覆蓋。 但看到 http://stackoverflow.com/questions/5409428/how-to-override-a-javascript-function – Guerra 2012-08-13 20:14:57

+0

@Guerra你肯定有原型的方式來包裝()的東西很好 – 2012-08-13 20:30:24

+0

IMO這是一個黑客來模擬面向對象覆蓋,但工作很好 – Guerra 2012-08-13 20:39:43

回答

29

從原型手動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 
}); 
+0

非常感謝你的提示安東。我會在早上玩它,看看它是如何執行的。 – 2012-08-13 20:53:49

+0

對於Magento的1.7這個工程:Product.Config.prototype.getOptionLabel = Product.Config.prototype.getOptionLabel.wrap – 2012-10-04 14:47:58

+0

想這取決於方法的命名 – 2012-10-05 07:16:57

26

只需添加到@安東-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); 
}); 
+2

非常感謝Vinai和Anton S提供的寶貴提示。我們已經改變了我們的臨時js黑客攻擊,現在它已經以正確的Magento方式完成了。你是石頭! – 2012-08-14 11:51:48

+0

@MilenPetrov接受幫助你改善SO體驗的答案,爲其他人搜索類似 – 2012-08-14 12:31:29

+0

@Anton S - 真的很抱歉,我忘了這麼做 – 2012-08-22 10:00:23