无法在指令linkFn中获取控制器引用

时间:2018-03-05 19:59:44

标签: angularjs typescript angularjs-directive

我正在尝试将angular-unit-converter指令移植到 angularjs@1.4.5 中的typescript。但是我无法使用angularjs为require指令注入控制器。

它抛出

  

无法读取未定义的属性'$ parsers'

因为ngModelundefined

这是我的尝试

// typescript conversion of https://github.com/alexandernst/angular-unit-converter
import { Decimal } from "decimal.js";
import { IDirective, IDirectiveFactory, IDirectiveLinkFn, IScope, INgModelController, IAttributes, IAugmentedJQuery } from "angular";

interface IUnitConverterScope extends IScope {
    [key: string]: any;
    convertFrom;
    convertTo;
}

export class UnitConverterDirective implements IDirective<IUnitConverterScope> {
    public link;
    public restrict = "A";
    public require: "ngModel";
    public template = "";
    public scope = {
        convertFrom: "@",
        convertTo: "@"
    };

    constructor() {
        // It's important to add `link` to the prototype or you will end up with state issues.
        // See http://blog.aaronholmes.net/writing-angularjs-directives-as-typescript-classes/#comment-2111298002 for more information.
        this.link = this._link.bind(this);
    }

    public static Factory(): IDirectiveFactory<IUnitConverterScope> {
        const directive = (/*list of dependencies*/) => {
            return new UnitConverterDirective(/*list of dependencies*/);
        };

        directive["$inject"] = [];

        return directive;
    }

    private _link(scope: IUnitConverterScope, element: IAugmentedJQuery, attrs: IAttributes, ngModel: INgModelController) {
        console.log(ngModel);
        Decimal.config({
            precision: 10
        });

        const units = {
            // Size/distance
            "mm": 0.001,
            "cm": 0.01,
            "m": 1,
            "km": 1000,
            "in": 0.0254,
            "ft": 0.3048,
            "yd": 0.9144,
            "mi": 1609.344,

            // Weight
            "mg": 0.001,
            "g": 1,
            "kg": 1000,
            "oz": 28.3495231,
            "lb": 453.59237
        };

        scope.do_convertFrom = (value) => {
            if (!scope.convertFrom || scope.convertFrom === "") { return value; }

            let from = new Decimal(units[scope.convertFrom]);
            let to = new Decimal(units[scope.convertTo]);
            return (new Decimal(value).dividedBy(from.dividedBy(to))).toNumber();
        };

        scope.do_convertTo = (value) => {
            if (!scope.convertTo || scope.convertTo === "") { return value; }

            let from = new Decimal(units[scope.convertFrom]);
            let to = new Decimal(units[scope.convertTo]);
            return (new Decimal(value).times(from.dividedBy(to))).toNumber();
        };

        let p = (viewValue) => {
            let m = viewValue.match(/^\-?\d+((\.|\,)\d+)?$/g);
            if (m !== null) {
                return scope.do_convertFrom(parseFloat(viewValue));
            }
        };
        let f = (modelValue) => {
            return scope.do_convertTo(parseFloat(modelValue));
        };

        ngModel.$parsers.push(p);
        ngModel.$formatters.push(f);

        scope.$watch("[convertFrom, convertTo]", () => {
            ngModel.$modelValue = "";
        });
    }
}

您可以看到实时DEMO(打开控制台以查看错误)

如果我只是写简单的JS它可以工作 - &gt; http://plnkr.co/edit/inuTNJ5OGhPHWmD09WWD?p=preview

我做错了什么?

1 个答案:

答案 0 :(得分:4)

这是因为永远不会定义require。它应该是

public require = "ngModel";

而不是

public require: "ngModel";

启用TypeScript strictNullChecks编译器选项可以消除此类错误。