2014-04-29 2 views
0

나는 DRY 원리를 적용하기 위해 Knockout에서 클래스 상속을하려하지만 은 성공하지 못했습니다.클래스 상속과 넉 아웃에서 메소드 덮어 쓰기

내가 달성하고자하는 것은 반복 코드 또는 많은 코드없이 몇 가지 유사점을 공유하는 2 가지 유형의 서버입니다.

일부 기능이 작동하지 않는 것으로 예상되는 최신 시도입니다.

부모 클래스 :

내가 생각
function BaseServer(options, builder) { 

    this.formatted_price = ko.computed(function() { 
    return utils.format_price(this.price(), options.prices.currency()); 
    }, this); 

    this.drives = ko.observableArray([]); 

    this.number_of_instances = ko.observable(1); 

    // Not sure if this is a good approach for this problem 
    for (i = 0; i < options.ssd.length; i++) { 
    self.drives.push(new builder.ssd(options.ssd[i], options.prices)); 
    } 
    for (i = 0; i < options.hdd.length; i++) { 
    self.drives.push(new builder.hdd(options.hdd[i], options.prices)); 
    } 

    // Will not work there is not this.cpu nor this.ram 
    this.price = ko.computed(function() { 
    var total = 0 
    total += this.cpu.price(); 
    total += this.ram.price(); 
    total += _.reduce(this.drives(), function(mem, drive) { 
     return drive.price(); 
    }, 0); 
    return total; 
    }, this); 
} 

일이 잘못이다 : 부모가, CPU 변수를 램에 액세스 할 수 없습니다 때문에

  • 가격 기능이 작동하지 않습니다.
  • 빌더 방법은 나에게이 결과를 달성하는 정말 이상한 방법 인 것처럼 보이지만 작동합니다.
  • 클래스에 의해 호출되는 인수 옵션에 함수를 전달하고 있습니다.

그런 다음 아이들. 내가 생각

function ServerGama(options){ 
    // Constructors for disks 
    var builder = { 
     ssd: SsdGama, 
     hdd: HddGama 
     }, 
     self = this; 
    ko.utils.extend(self, new BaseServer(options, builder)); 

    // Normal attributes 
    self.cpu = new CpuGama(options.cpu.up, options.cpu.down, options.prices); 
    self.ram = new RamGama(options.ram.up, options.ram.down, options.prices); 
} 

function ServerBeta(options){ 
    var builder = { 
     ssd: SsdBeta, 
     hdd: HddBeta 
     }, 
     self = this; 
    ko.utils.extend(self, new BaseServer(options, builder)); 

    // Normal attributes 
    self.cpu = new CpuBeta(options.cpu, options.prices); 
    self.ram = new RamBeta(options.ram, options.prices); 
    self.licenses = new server_licenses([ 
    { 
     'name': 'Server 2008', 
     'price': options.prices.cost_per_2008 
    }, 
    { 
     'name': 'Server 2009', 
     'price': options.prices.cost_per_2009 
    } 
    ], options.prices.currency, options.choice); 
    // This price does not seem to overwrite BaseServer price 
    this.price = ko.computed(function() { 
    // This will not work because we are losing the biding that price is making to the cpu, ram, disk variables 
    var total = this.price.call(this); 
    total += self.licenses.price(); 
    return total; 
    }, 0); 
    }, this); 
} 

상황이 잘못 : 부모로부터

  • FORMATTED_PRICE 습관이는 BetaServer 클래스에서 덮어 사용합니다.
  • 은 아마 다른 방법

답변

1

이 당신의 모든 질문에 답변을하지 않습니다에 디스크를 만들 수 있지만, 여기에 내가 상속 및 덮어 쓰기 방법을 처리하는 것을 선호하는 방법의 예 :

var SuperClass = function(options) { 
    var self = this; 

    options = options || {}; 

    self.value = ko.observable(options.value); 

    self.computed = ko.computed(function() { 
     return self.value() + 100; 
    }); 
}; 

var SubClass = function(options) { 
    var self = this; 

    // call super constructor 
    self.constructor.call(self, options); 

    // save method from super 
    var super_computed = self.computed; 

    // overwrite method on child class 
    self.computed = ko.computed(function() { 
     // use saved super method in the overwritten method 
     return super_computed() + 5; 
    }); 
}; 
SubClass.prototype = new SuperClass(); 

var sub = new SubClass({ value: 1 }); 
console.log(sub.computed()); // should be 106 

var sub2 = new SubClass({ value: 2 }); 
console.log(sub2.computed()); // should be 107 

은 여기 JSFiddle이 방법 보여주는 것 : http://jsfiddle.net/szQRb/1/

+0

참조하십시오. 그러나 그것은 내가 찾고있는 것처럼 보입니다. Js는 일반적인 문제를 해결하기위한 결정적인 패턴을 찾기가 정말 어려워 수업을 만드는 방법에 대한 많은 자원을 가지고 있습니다. Charlie에게 고마워. – user1634074

1

내가 JS에서 "클래스"를 원하는 경우를, 나는 TypeScript로 전환 :

373,242,이 다음 JS로 컴파일 할 TypeScript playground here

참조 :

var __extends = this.__extends || function (d, b) { 
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 
    function __() { this.constructor = d; } 
    __.prototype = b.prototype; 
    d.prototype = new __(); 
}; 
var Drive = (function() { 
    function Drive() { 
     this.price = ko.observable(5); 
    } 
    return Drive; 
})(); 
var BaseServer = (function() { 
    function BaseServer() { 
     var _this = this; 
     this.drives = ko.observableArray([new Drive()]); 
     this.price = ko.computed({ 
      owner: this, 
      read: function() { 
       return _this.drives()[0].price(); 
      } 
     }); 
    } 
    return BaseServer; 
})(); 

var ServerGama = (function (_super) { 
    __extends(ServerGama, _super); 
    function ServerGama() { 
     _super.apply(this, arguments); 
     var _this = this; 
     this.price = ko.computed({ 
      owner: this, 
      read: function() { 
       return _this.price() + 1; 
      } 
     }); 
    } 
    return ServerGama; 
})(BaseServer); 

내가 이것을 시도해야 http://jsfiddle.net/sjroesink/Pm6zq/

관련 문제