简体   繁体   中英

Directive cannot read a property from “attrs”

I have this link function in my directive:

link: function(scope, element, attrs, ngModel) {
    ngModel.$formatters.push(function(value) {
        return $filter('number')(value, 0);
    });

    element.bind('keyup', function($event) {
        var start = this.selectionStart;
        var end = this.selectionEnd;
        if ($event.keyCode < 36 || $event.keyCode > 40) {
            var valor = ngModel.$viewValue;
            valor = valor.replace(/\./g, '');
            valor = valor.replace(/[a-zA-Z]/g, '');

            console.log(attrs.paramX);

            element.val($filter('number')(valor, 0) || "");
            if ($event.keyCode !== 8 && valor.length % 3 == 1) {
                this.setSelectionRange(start + 1, end + 1);
            } else {
                this.setSelectionRange(start, end);
            }
        }
    });
}

And i can not see the variable "attrs" please someone can help me with this error.

The error is "Cannot read property 'paramX' of undefined(…)"

Do you have an isolated scope in that directive? If your answer is yes, you can use your own defined parameters. Check this: https://docs.angularjs.org/guide/directive , in section "Isolating the Scope of a Directive".

On the other hand, if you can't use an isolated scope to get the attribute from outside you can add "attrs" into scope to be accessible from everywhere inside the directive. It's a bit hacky solution and probably the less optimal, but may work. Your code would be like that:

link: function(scope, element, attrs, ngModel) {
    /*
     * INITIALIZATION
     */
    scope.attrs = attrs;

    ngModel.$formatters.push(function(value) {
        return $filter('number')(value, 0);
    });

    element.bind('keyup', function($event) {
        var start = this.selectionStart;
        var end = this.selectionEnd;
        if ($event.keyCode < 36 || $event.keyCode > 40) {
            var valor = ngModel.$viewValue;
            valor = valor.replace(/\./g, '');
            valor = valor.replace(/[a-zA-Z]/g, '');

            /*
             * SCOPE ATTRS
             */
            console.log(scope.attrs.paramX);

            element.val($filter('number')(valor, 0) || "");
            if ($event.keyCode !== 8 && valor.length % 3 == 1) {
                this.setSelectionRange(start + 1, end + 1);
            } else {
                this.setSelectionRange(start, end);
            }
        }
    });
}

This crappy solution doesn't offer binding at all, so the first attrs value will remain in the scope variable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM