Daktilo Katmalar

oy
6

Ben typescript etrafında oynuyorum ve ben bir kaç var fonksiyonel katmalar , Eventableve Settableben için mixin istediğinizi, Model(bir backbone.js modeli gibi bir şey taklit) sınıfının:

function asSettable() {
  this.get = function(key: string) {
    return this[key];
  };
  this.set = function(key: string, value) {
    this[key] = value;
    return this;
  };
}

function asEventable() {
  this.on = function(name: string, callback) {
    this._events = this._events || {};
    this._events[name] = callback;
  };
  this.trigger = function(name: string) {
    this._events[name].call(this);
  }
}

class Model {
  constructor (properties = {}) {
  };
}

asSettable.call(Model.prototype);
asEventable.call(Model.prototype);

Yukarıdaki kod çalışıyor fakat bunun karma yöntemlerden birini kullanmaya çalıştı eğer derlemek olmaz (new Model()).set('foo', 'bar').

Ben bu çalışabilirsiniz

  1. ekleyerek interfaceMixins için bildirimleri
  2. Sahte ilan get/ set/ on/ triggeryöntemleri Modelbeyan

kukla bildirimleri etrafında temiz bir yolu var mı?

Oluştur 04/10/2012 saat 04:20
kaynak kullanıcı
Diğer dillerde...                            


3 cevaplar

oy
12

İşte kullanarak katmalar yaklaşım bir yolu interfacesve bir static create()yöntemi. Bu yeniden tanımlamak zorunda engeller böylece Arayüzler birden devralmayı destekler interfacessizin Mixins ve static create()yöntem bir örneğini size geri vererek ilgilenir Model()bir şekilde IModel( <any>dökme bir derleyici uyarı baskılamak için gereklidir.) Sen her çoğaltmak gerekir için üye tanımları Modelüzerinde IModelberbat ama sen typescript geçerli sürümünde istediğini elde etmek için en temiz yol gibi görünüyor.

düzenleme: Ben destekleyen Mixins için biraz daha basit bir yaklaşım tespit ettik ve hatta onları tanımlamak için bir yardımcı sınıf oluşturduk. Ayrıntılar bulunabilir buraya .

function asSettable() {
  this.get = function(key: string) {
    return this[key];
  };
  this.set = function(key: string, value) {
    this[key] = value;
    return this;
  };
}

function asEventable() {
  this.on = function(name: string, callback) {
    this._events = this._events || {};
    this._events[name] = callback;
  };
  this.trigger = function(name: string) {
    this._events[name].call(this);
  }
}

class Model {
  constructor (properties = {}) {
  };

  static create(): IModel {
      return <any>new Model();
  }
}

asSettable.call(Model.prototype);
asEventable.call(Model.prototype);

interface ISettable {
    get(key: string);
    set(key: string, value);
}

interface IEvents {
    on(name: string, callback);
    trigger(name: string);
}

interface IModel extends ISettable, IEvents {
}


var x = Model.create();
x.set('foo', 'bar');
Cevap 04/10/2012 saat 06:46
kaynak kullanıcı

oy
3

hala, çift türü bildirimleri gerektiren bir modül olarak mixin tanımlamaktır Hintçe temiz yolu, bunu yapmak için:

module Mixin {
    export function on(test) {
        alert(test);
    }
};

class TestMixin implements Mixin {
    on: (test) => void;
};


var mixed = _.extend(new TestMixin(), Mixin); // Or manually copy properties
mixed.on("hi");

kullanarak arayüzleri bir alternatif (sen Mixins için ortak-bir arayüz oluşturmanız gerekir rağmen, çünkü çoklu-devralma) sınıfları ile bunu kesmek için:

var _:any;
var __mixes_in = _.extend; // Lookup underscore.js' extend-metod. Simply copies properties from a to b

class asSettable {
    getx(key:string) { // renamed because of token-clash in asEventAndSettable
        return this[key];
    }
    setx(key:string, value) {
        this[key] = value;
        return this;
    }
}

class asEventable {
    _events: any;
    on(name:string, callback) {
        this._events = this._events || {};
        this._events[name] = callback;
    }
    trigger(name:string) {
        this._events[name].call(this);
  }
}

class asEventAndSettable {
   // Substitute these for real type definitions
   on:any;
   trigger:any;
   getx: any;
   setx: any;
}

class Model extends asEventAndSettable {
    /// ...
}

var m = __mixes_in(new Model(), asEventable, asSettable);

// m now has all methods mixed in.

Ben Steven'ın yanıt yorumladı gibi, Katmalar gerçekten typescript özelliği olmalıdır.

Cevap 04/10/2012 saat 07:04
kaynak kullanıcı

oy
1

Bir çözüm 'yeni' anahtar sözcüğü ek olarak typescript sınıf sistemini, ancak türleri ve arayüzleri sadece Systeme kullanmayın etmektir.

    //the function that create class
function Class(construct : Function, proto : Object, ...mixins : Function[]) : Function {
        //...
        return function(){};
}

module Test { 

     //the type of A
    export interface IA {
        a(str1 : string) : void;
    }

    //the class A 
    //<new () => IA>  === cast to an anonyme function constructor that create an object of type IA, 
    // the signature of the constructor is placed here, but refactoring should not work
    //Class(<IA> { === cast an anonyme object with the signature of IA (for refactoring, but the rename IDE method not work )
    export var A = <new () => IA> Class(

        //the constructor with the same signature that the cast just above
        function() { } ,

        <IA> {
            //!! the IDE does not check that the object implement all members of the interface, but create an error if an membre is not in the interface
            a : function(str : string){}
        }
    );


    //the type of B
    export interface IB {
        b() : void;
    }
    //the implementation of IB
    export class B implements IB { 
        b() { }
    }

    //the type of C
    export interface IC extends IA, IB{
        c() : void;
        mystring: string;
    }

     //the implementation of IC
    export var C = <new (mystring : string) => IC> Class(

        //public key word not work
        function(mystring : string) { 

            //problem with 'this', doesn't reference an object of type IC, why??
            //but google compiler replace self by this !!
            var self = (<IC> this);
            self.mystring = mystring;
        } ,

        <IC> {

            c : function (){},

            //override a , and call the inherited method
            a: function (str: string) {

                (<IA> A.prototype).a.call(null, 5);//problem with call and apply, signature of call and apply are static, but should be dynamic

                //so, the 'Class' function must create an method for that
                (<IA> this.$super(A)).a('');
            }

        },
        //mixins
        A, B
    );

}

var c = new Test.C('');
c.a('');
c.b();
c.c();
c.d();//ok error !
Cevap 23/01/2013 saat 00:34
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more