需要帮助将指令迁移到Angular2

时间:2016-03-22 11:08:06

标签: angular angular2-directives

我有一个名为NgtsAjax的指令,该指令对传递给path属性的网址发出ajax请求,你可以这样使用:

<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的{​​{1}}属性,以我将要解释的特殊方式。

我得到url值并使用mustache语法检测是否有参数,如果使用它我得到每个参数并且我保留在名为url的参数列表中,最后我观察pathVariables属性的变化,当path被更改时,我检查path中的每个参数是否都有值,并且它都有值并使用$ http来运行ajax请求。

这些是控制器的相关代码:

pathVariables

我这样做是因为path属性可以有多个变量/表达式,例如:

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

}

为了发出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)" /> customerId具有值。

您可以查看完整的指令源代码here

然后,我不确定如何实现这个,我不确定它是否必须是@Directive或@Component而且我不知道如何解决路径上的变量问题。

你认为这是最好的方法吗?

更新1 :问题不在于是否使用指令或组件......问题是invoiceId属性行为。

更新2 :中间/黑客/修补/解决方案。

我插入了一些限制以使其有效我强制在方括号([]之间的path上写变量,这样:

path

有了这个,我可以确定变量是否为空,寻找&#34; []&#34;。

我已经用这种方式定义了指令:

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

如果您知道其他更好的方法,请告诉我们;)

1 个答案:

答案 0 :(得分:0)

组件和指令之间的唯一区别是,组件具有视图。我认为它应该是一个看不见的行为元素,你不需要一个视图。因此请使用Directive