2016-03-22 2 views
0

У меня есть директива под названием NgtsAjax, директива делает запрос Ajax к URL передается на path атрибута, вы можете использовать этот способ:Нужна помощь миграции директивы 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 
    } 
} 

Директива использует атрибут path, привязанный к url, особым образом. Я объясню это.

я получаю значение url и обнаружить, если имеют параметров с использованием синтаксиса усов, если использует его я получаю каждый параметр и я держу в списке параметров называется pathVariables, по последнему я наблюдаю атрибут path для изменений, когда path является изменено. Я проверяю, имеет ли значение каждый параметр в pathVariables, и все они имеют значения и используют $ http для запуска запроса ajax.

Это соответствующие фрагменты кода контроллера:

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

} 

я сделать это таким образом, потому что атрибут путь может иметь несколько переменных/выражений, например:

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

Для того, чтобы сделать ajax-запрос Я должен быть уверен, что customerId и invoiceId имеют значения.

Вы можете посмотреть полный исходный код директивы 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

Не знаете, в чем проблема. Возможно, вы хотите сделать ввод setter '@Input() set path (value: string) {...}' для выполнения некоторого кода при обновлении значения или реализации 'ngOnChanges()', который вызывается, когда входное значение изменения. –

Смежные вопросы