2013-03-11 3 views
8

Ist es möglich, Typoskript zu zwingen, Methoden auf die Instanz zu setzen, nicht auf den Prototyp. Ich frage das, weil ich häufig "diesen" Bereich Probleme habe, mit denen Methoden auf dem Prototyp Probleme verursachen.Force typescript, um Methoden auf die Instanz zu setzen, nicht den Prototyp

bearbeiten


Zum Beispiel in der Ausgabe von dem ts es inkonsistent scheint, halte ich die FooAlert in der FooViewModel Funktion, sondern die Methode openFooAlertDialogueAdd im Prototyp

Js

var FooViewModel = (function() { 
    function FooViewModel (json) { 
     this.Foolert = ko.observable(); 

    } 
    FooViewModel.prototype.openFooAlertDialogueAdd = function() { 
     this.FooAlert = something; 
    }; 

Ts

class FooViewModel{ 
    FooAlert = KnockoutObservableAny 

     constructor(){ 
     this.FooAlert = ko.observable(); 
     } 
    openFooAlertDialogueAdd() { 
     this.FooAlert = something; 
    }; 

} 

Antwort

4

Die Methoden des Prototyps sind die Methoden, die für jede Instanz verfügbar sind.

class Example { 
    constructor(private someProperty: string) { 

    } 

    method() { 
     return this.someProperty; 
    } 
} 

var exampleA = new Example('A'); 
var exampleB = new Example('B'); 
var exampleC = new Example('C'); 

console.log(exampleA.method()); // A 
console.log(exampleB.method()); // B 
console.log(exampleC.method()); // C 

haben Jede Instanz der someProperty und method() seinen Prototyp kopiert. Sie können dies mit Hilfe überprüfen:

alert(exampleC.hasOwnProperty('someProperty') ? 'Yes' : 'No'); 

Es ist nur, wenn die Instanz nicht über eine eigene Eigenschaft hat, die JavaScript wird jede Abhängigkeitskette zu Fuß bis zu der Eigenschaft auf eine Klasse höher die Abhängigkeitskette zu finden.

Wenn Sie den Code, wo Sie Probleme mit dem Umfang von this haben, bin ich sicher, dass wir Ihnen helfen können, es zu beheben.

+0

Ich habe eine Bearbeitung gemacht :) – FutuToad

+0

Ich denke, ich muss openFooAlertDialogueAdd = Funktion usw. tun, da das gibt die richtige Js-Ausgabe – FutuToad

+0

Legen Sie den Ausgang JS für einen Moment auf eine Seite - weil ich denke, dass das nicht zählt - kann Sie zeigen ein Beispiel für das Scope-Problem? Ich denke, Sie wollen das Problem lösen, dass ich Dinge statisch mache, aber ich denke, dass es wahrscheinlich einen besseren Weg gibt. Der statische Fix soll dem statischen Schlüsselwort vorangestellt werden: 'static openFooAlertDialogueAdd() ...' – Fenton

12

Wenn Sie Probleme mit dem Oszilloskop haben, fühle ich mich schlecht für Sie Sohn, ich habe 99 Probleme, aber das ist nicht eins!

Steves Antworten zeigen die korrekte Methode zum Definieren von Klassenmethoden, Methoden, die für jede Instanz verfügbar gemacht werden. Wenn jedoch Probleme mit dem Oszilloskop auftreten, liegt das wahrscheinlich daran, dass Sie diese Methoden aus einem anderen Kontext aufrufen. Wenn Sie beispielsweise Knockout verwenden und eine dieser Methoden an eine click-Bindung binden, überschreibt Knockout den Bereich auf den aktuellen Bereich der Bindung, NICHT den Bereich, für den Sie die Methode definiert haben.

Es gibt zwei Optionen, um diesen Verlust des Bereichs zu verhindern.

Erstens können Sie Ihre Methoden im Konstruktor definieren, um sie auf der Instanz statt auf dem Prototyp verfügbar zu machen.

Like:

class Greeter { 
    greet:() => string; 
    greeting: string; 

    constructor(message: string) { 
     this.greeting = message; 
     this.greet =() => { 
      return "Hello, " + this.greeting; 
     } 
    } 

Zweitens könnte man die => Syntax Umfang Klassenmethoden verwenden.

Beispiel:

class Greeter { 
    greeting: string; 
    constructor() { 
     this.greeting: "Blabla"; 
    } 
    greet=() => { 
     alert(this.greeting); 
    } 
} 
+3

+1 für den Kommentar zu knockout, der den Bereich ändert. konnte nicht herausfinden, was falsch war. –

+0

gibt es keine Möglichkeit, Knockout zu sagen, es nicht zu tun? Ich möchte meine Methoden außerhalb des Konstruktors definieren, wie es schöner aussieht :) –

+0

@ s093294 AFAIK gibt es eine andere Möglichkeit, die nur mit Click-Handlern funktionieren würde. Sie können 'ko.contextFor (event.target). $ Root' verwenden, um den Root-Bereich des Elements zu erhalten, auf das Sie gerade geklickt haben. – thomaux

0

Es sieht aus wie dies ein Typoskript/Knockout Frage ist, wie @Anzeo wie in seiner Antwort darauf hingewiesen, auch Ihre bearbeiten.Ich habe das Problem gelöst, indem ich meine Methodendeklarationen in den Konstruktor eingefügt habe, aber auch die var self = this; Konvention verwendet habe, die im Abschnitt "Managing 'this'" unter Knockout's Computed Observable documentation aufgeführt ist. Sie TS Code könnte wie folgt aussehen:

class FooViewModel{ 
    FooAlert: KnockoutObservableAny; 
    openFooAlertDialogueAdd:() => void; 

    constructor(){ 
     var self = this; 
     self.FooAlert = ko.observable(); 
     self.openFooAlertDialogueAdd = function(){ 
      self.FooAlert('whatever your FooAlert observable takes'); 
     }; 
    } 
} 

Egal welchen Umfang Änderung auftreten könnte, der JavaScript-Verschluss um self Sie hält etwa this Wechsel zu kümmern. Das sollte beide Probleme lösen.

+0

Mit '=>' (die Pfeil-oder Lambda-Funktion) wird dauern Kopieren Sie diesen Bereich für Sie, damit Sie ihn nicht selbst kopieren müssen. – thomaux

+0

@Anzeo, Das wird es! Danke, dass du darauf hingewiesen hast. Ich denke, ich bevorzuge immer noch die explizite Kopie mit der Selbstkonvention. Es macht jedoch den Konstruktor überflutet, so dass ich vielleicht mehr mit Lambda arbeiten würde. – DBueno

Verwandte Themen