2016-03-22 20 views
0

Ich habe eine Richtlinie genannt NgtsAjax, die Richtlinie über path Attribut übergeben eine Ajax-Anforderung an eine URL macht Sie auf diese Weise verwenden können:Brauchen Sie Hilfe Richtlinie Angular2 Migration

<ngts-ajax path="/api/customer/{{customerId}}" as="customer" on-success="ctrl.load(customer)" /> 

Die Richtlinie Fabrik ist:

function NgtsAjaxFactory() { 
    return {  
     restrict: "E", 
     bindToController: true, 
     scope: { 
      url: "@path", 
      as: "=as", 
      httpVerb: "@verb", 
      onFail: "&onFail", 
      onSuccess: "&onSuccess" 
     }, 
     controller: NgtsAjax, 
     priority: 20000 
    } 
} 

Die Direktive verwendet das path Attribut, gebunden an url, auf eine spezielle Art und Weise werde ich es erklären.

Ich erhalte den url Wert und erkennen, ob Parameter hat Schnurrbart-Syntax, wenn es verwendet erhalte ich jeden Parameter und ich halte auf einer Parameterliste pathVariables, von zuletzt rief ich das path Attribut für Änderungen beobachten, wenn path ist geändert Ich überprüfe, ob jeder Parameter in pathVariables Wert hat und alle Werte haben und verwende $ http, um eine AJAX-Anfrage auszuführen.

Dies sind die relevanten Teile des Codes des Steuerpults:

class NgtsAjax { 
    //... class attributes 
    //... 
    constructor($scope, private $interpolate, private $attrs, ....) 
     this.pathAttr = $attrs.path; 
     .... 
     .... 
     this.parentScope = $scope.$parent; 
     this.observePath(); 
    } 

    private observePath() { 
     if (!this.url) 
      this.url = this.$location.path(); 
      this.pathVariables = []; 
     else { 
      // Gets variables in path attribute 
      const pathVariables = this.pathVariables = this.pathAttr.match(/{{[\w.\s|:$']+}}/g) || []; 
      if (pathVariables) { 
       for (let i = 0; i < pathVariables.length; i++) { 
        pathVariables[i] = pathVariables[i].toString(); 
       } 
      } 
     } 
     this.$attrs.$observe("path",() => { 
      if (this.pathVariablesHaveValues()) 
       this.run(); 
     }); 
    } 

    private pathVariablesHaveValues() { 
     let result = true; 
     const pathVariables = this.pathVariables; 
     for (let i = 0; i < pathVariables.length; i++) { 
      const interpolation = pathVariables[i]; 
      const expression = this.$interpolate(interpolation); 
      if (!expression(this.parentScope)) { 
       result = false; 
       break; 
      } 
     } 
     return result; 
    } 

} 

ich es auf diese Weise tun, weil Pfad Attribut mehr Variablen/Ausdrücke haben kann, zum Beispiel:

<input type="text" ng-model="model.customerId"/> 
<input type="text" ng-model="model.invoiceId"/> 

<ngts-ajax path="/api/customer/{{model.customerId}}/invoice/{{model.invoiceId}}" as="customerInvoice" on-success="ctrl.load(customerInvoice)" /> 

Um zu machen die Ajax-Anfrage muss ich sicher sein, dass customerId und invoiceId Werte haben.

Sie können den vollständigen Quellcode der Direktive here ansehen.

Dann bin ich mir nicht sicher, wie die Implementierung von diesem zu nähern, ich bin mir nicht sicher, ob es eine @Directive oder eine @Component sein muss und ich habe keine Ahnung, wie das Problem lösen der Weg.

Was halten Sie für den besten Ansatz?

Update 1: Die Frage ist nicht, ob Richtlinie oder Komponente verwenden ... das Problem ist die path Attribut-Verhalten.

Update 2: Eine mittlere/Hacking/Patching/... Lösung.

ich einfügen habe eine kleine Einschränkung zu machen, es funktioniert Ich zwinge Variablen auf path zwischen eckigen Klammern schreiben ([]) auf diese Weise:

<em-ajax path="/api/customer/[{{model?.customerId}}]/invoice/[{{model?.invoiceId}}]"></em-ajax> 

Damit ich bestimmt, wenn die Variablen leer suchen "[]"

Ich habe die Richtlinie auf diese Weise definiert:

@Directive({ 
    selector: "em-ajax", 
}) 
export class EmAjax implements OnChanges { 
    @Input() path : string; 
    ... 
    ... 

    ngOnChanges() { 
     if (this.pathIsValid()) { 
      this.run(); 
     } 
    } 

    pathIsValid() { 
     if (this.path.indexOf("[]") >= 0) { 
      return false; 
     } 
     return true; 
    } 

    run(params? : any) { 
     let path = this.path.replace("[", "").replace("]", ""); 
     // `path` is the real url 
     // I can launch http request 
    } 
    ... 
    ... 
} 

Wenn Sie wissen, anderen Weg, es besser zu machen, lassen Sie mich wissen;)

Antwort

0

Der einzige Unterschied zwischen Komponente und der Richtlinie ist, dass eine Komponente hat eine Aussicht. Ich gehe davon aus, dass es sich um ein unsichtbares Verhaltenselement handeln sollte und Sie keine Ansicht benötigen. Gehen Sie deshalb mit Directive.

+0

Ok, aber das eigentliche Problem ist das Verhalten mit 'Pfad' Attribut. –

+0

Nicht sicher, worum es bei dem Problem geht. Vielleicht möchten Sie die Eingabe zu einem Setter '@Input() set path (value: string) {...}' machen, um Code auszuführen, wenn der Wert aktualisiert wird, oder implementieren Sie 'ngOnChanges()', das bei einem Eingabewert aufgerufen wird Änderungen. –