Need help migrating directive to Angular2

Discussão em 'Angular' iniciado por Javier Ros, Junho 25, 2025.

  1. Javier Ros

    Javier Ros Guest

    I have a directive called NgtsAjax, the directive makes a ajax request to an URL passed on path attribute, you can use this way:

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


    The directive factory is:

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


    The directive uses the path attribute, bound to url, in a special way I'm going to explain it.

    I get the url value and detect if has parameters using moustache syntax, if uses it I get each parameter and I keep on a parameter list called pathVariables, by last I observe the path attribute for changes, when path is changed I check if each parameter in pathVariables has value and it all have values and use $http to run ajax request.

    These are the relevant pieces of code of controller:

    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 = pathVariables.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;
    const expression = this.$interpolate(interpolation);
    if (!expression(this.parentScope)) {
    result = false;
    break;
    }
    }
    return result;
    }

    }


    I do it this way because path attribute can have several variables/expressions, for example:

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


    In order to make the ajax request I have to be sure that customerId and invoiceId have values.

    You can look at the full directive source code here.

    Then, I'm not sure how to approach the implementation of this, I'm not sure if it have to be a @Directive or a @Component and I'm have no idea how to resolve the variables issue on the path.

    Which do you think is the best approach?

    Update 1: The question is not if use Directive or Component ... the problem is the path attribute behavior.

    Update 2: A middle/hacking/patching/... solution.

    I have insert a little restriction to make it works I force to write variables on path between square brackets ([]) this way:

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


    With this I can determinate if the variables are empty looking for "[]".

    I have defined the directive this way:

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


    If you know other way to do it better, let me know.

    Continue reading...

Compartilhe esta Página