2016-03-22 9 views
0

をディレクティブの移行に役立つ、ディレクティブはpath属性に渡されたURLにAJAX要求を行い、あなたがこの方法を使用することができます必要があります。私はディレクティブは<code>NgtsAjax</code>呼ばれていAngular2

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

ディレクティブの工場がある:

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

このディレクティブは、urlにバインドされたpathという属性を使用しています。これについては、特別な方法で説明します。

私はpathがあるときに、最後で、私は、変更のpath属性を観察し、それを使用している場合、私は、各パラメータを取得し、私はpathVariablesと呼ばれるパラメータリストに保つ、url値を取得し、口ひげの構文を使用してパラメータを持っているかどうかを検出変更しましたpathVariablesの各パラメータに値があり、すべてが値を持ち、$ httpを使用してajax要求を実行しているかどうかを確認しました。

<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)" /> 

作るために:私はパス属性は、いくつかの変数/式を持つことができるので、例えば、このようにそれを行う

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; 
    } 

} 

これら

は、コントローラのコードの関連部分ですアヤックスのリクエスト私は customerIdinvoiceIdに値があることを確認する必要があります。

完全なソースコードhereを見ることができます。

次に、この実装にどのようにアプローチするのかよく分かりませんが、@ Directiveまたは@Componentでなければならないかどうかはわかりませんし、変数の問題を解決する方法がわかりませんパス。

あなたは最善のアプローチだと思いますか?

更新1:指示またはコンポーネントを使用している場合は、問題はpath属性の問題です。

更新2:中間/ハッキング/パッチ適用/解決策。

私はそれは私が角括弧([])の間pathに変数を書くためにこの方法を強制的に動作させるには少し制限挿入しています:変数が探して空になっている場合、私は確定でき

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

を"[]"。

私はディレクティブをこのように定義しています

@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 
    } 
    ... 
    ... 
} 

方が良いそれを行うために他の方法を知っている場合、私に知らせ;)

答えて

0

コンポーネントとディレクティブの唯一の違いは、コンポーネントのこと眺めがある。私はそれが目に見えない行動のみの要素でなければならないと仮定し、あなたは視点を必要としません。したがってDirectiveに行ってください。

+0

しかし、本当の問題は 'path'属性の動作です。 –

+0

問題の原因がわかりません。おそらく、値が更新されたときに何らかのコードを実行するために入力を '@Input()set path(value:string){...}'に設定したい場合や、入力値が更新されたときに呼び出される 'ngOnChanges()変更。 –

関連する問題