获取角度指令属性值返回'undefined'

时间:2013-10-21 12:13:32

标签: angularjs angularjs-directive

我正在为输入掩码做一个指令。但是,当我将字符串作为值传递时,属性未定义。如果我直接传递面具它正在工作。

.directive('inputMask', function () {
return {
    restrict: 'EAC',
    scope: true,
    link: function (scope, element, attrs) {
        scope.$watch('inputMask', function (newVal) {
            console.log('inputMask', newVal);
        });
        var maskType = scope.$eval(attrs.inputMask);
        switch (maskType) {
            case 'phone':
                $(element).inputmask("phone", {
                    url: '@Url.Content("~/Scripts/jquery-inputmask/phone-codes/phone-codes.json")',
                    onKeyValidation: function () { //show some metadata in the console
                        console.log($(this).inputmask("getmetadata")["name_en"]);
                    }
                });
                break;
            case 'money':
                $(element).inputmask("decimal", { digits: 2 });
                break;
            case 'moneyGrouped':
                $(element).inputmask("decimal", {
                    radixPoint: ",",
                    autoGroup: true,
                    groupSeparator: ".",
                    groupSize: 3,
                    digits: 2
                });
                break;
            case 'email':
                $(element).inputmask('Regex', { regex: "[a-zA-Z0-9._%-]+@[a-zA-Z0-9-]+\\.[a-zA-Z]{2,4}" });
            default:
                $(element).inputmask(maskType);
        }

        $(element).inputmask(scope.$eval(attrs.inputMask));
        $(element).on('keypress', function () {
            scope.$eval(attrs.ngModel + "='" + element.val() + "'");
        });
    }
};
});

工作(将进入默认的开关):

<input type="teste" name="teste" value="" ng-model="form.email" input-mask='{ "mask": "d/m/y", "autoUnmask" : true}'/>

不能正常工作, attrs.inputMask undefined(如果输入“money”,则应该输入):

<input type="teste" name="teste" value="" ng-model="form.email" input-mask='money'/>

有什么问题?

3 个答案:

答案 0 :(得分:3)

使用scope: true时,将为此指令创建新范围。然后,在$watch正常工作的情况下,您应该为当前范围创建一个名为inputMask的新属性,该属性接收attrs.inputMask

scope.inputMask = attrs.inputMask;
scope.$watch('inputMask', function (newVal) {
    console.log('inputMask', newVal);
});

您可以看到简化的工作小提琴here

另一个选择是在指令的范围属性中使用a哈希对象。

directive docs写道:

  

{}(对象哈希) - 创建一个新的“隔离”范围。 '孤立'   范围与正常范围不同,因为它不是原型   从父范围继承。这在创建可重用时很有用   组件,不应该意外地读取或修改数据   父范围。

     

(...)

     

@或@attr - 将本地范围属性绑定到DOM属性的值。

这样,您可以创建绑定DOM属性的范围:

scope: { 
    inputMask: "@" 
},
link: function (scope, element, attrs) {
    scope.$watch('inputMask', function (newVal) {
        console.log('inputMask', newVal);
    });
    /* ... */
}

Fiddle

答案 1 :(得分:0)

在指令使用中,

范围:{inputMask:'@'}

在链接函数中,而不是使用attr.inputMask,使用scope.inputMask,这将起作用。

如果你想使用attr那么你可以使用

attr.$observe('inputMask', function() {
    console.log('changed');
}

因为最初的值将是未定义的。

答案 2 :(得分:0)

这里的实际问题是范围。$ eval('money')将返回undefined。 该属性应该链接到指令,如果它是大括号{},或者它是一个字符串,如'money'。

这就是你正在做的导致问题的价值。

var maskType = scope.$eval(attrs.inputMask);

如果要传递插值属性,例如{{money}},则只需要使用带@或attrs的隔离范围。$ observe。