attrs。$在范围内设置。$ watch函数保持指令忙

时间:2014-08-24 09:16:37

标签: angularjs angularjs-directive angularjs-scope

我在下面的plunker有一个联系验证指令...... http://plnkr.co/edit/9kgZgW?p=info

return {
  restrict: 'A',
  link: function(scope, elem, attrs, controller) {
    var fieldValue;
    var checker = function() {

      // Get the value of the field type
      var dateType = elem.inheritedData("$formController")[attrs.formFieldValidate];
      var dataTypeValue = dateType.$viewValue;

      // get the field value to be validated against the field type
      fieldValue = scope.$eval(attrs.ngModel);

      switch (dataTypeValue) {
        case "Email":
          attrs.$set('placeholder', 'username@example.com');
          return (fieldValue && VALID_EMAIL.test(fieldValue)) ? true : false;
        case "Phone":
          attrs.$set('placeholder', '1234567890 | 123 456 7890 | (123) 456-7890 | 123-456-7890');
          return (fieldValue && VALID_PHONE.test(fieldValue)) ? true : false;
        case "IM":
          attrs.$set('placeholder', 'username@example.com');
          return (fieldValue && VALID_IM.test(fieldValue)) ? true : false;
        default:
          attrs.$set('placeholder', 'Details');
          return false;
      }
    };
    scope.$watch(checker, function(valid) {
      scope.validField = valid;
      return valid ? fieldValue : undefined;
    });
  }
};

除IE10和IE11外,代码工作正常,其中checker函数运行无限时间。初步调查显示attrs。默认开关案例中的$ set使其保持运行状态。结果是浏览器被冻结。

你能指出,我如何制作范围。$ watch使用attrs。$ set in a directive?

请注意,问题仅在IE10和IE11中。

1 个答案:

答案 0 :(得分:0)

这似乎是由于IE设置input值时触发placeholder事件的事实。

您可以在此issue中找到有关此奇怪的IE行为的更多详细信息。

作为一种解决方法,您可以将检查器更改为仅在值需要更新时设置新的placeholder属性:

var newPlaceholder = attrs.placeholder;
switch (dataTypeValue) {
    case "Email":
      newPlaceholder = 'username@example.com';
      result = (fieldValue && VALID_EMAIL.test(fieldValue)) ? true : false;
    case "Phone":
      newPlaceholder = '1234567890 | 123 456 7890 | (123) 456-7890 | 123-456-7890';
      result = (fieldValue && VALID_PHONE.test(fieldValue)) ? true : false;
    case "IM":
      newPlaceholder = 'username@example.com';
      result =  (fieldValue && VALID_IM.test(fieldValue)) ? true : false;
    default:
      newPlaceholder =  'Details';
      result = false;
}
if(newPlaceholder !== attrs.placeholder){
    attrs.$set('placeholder', newPlaceholder);
}
return result;

似乎有一个类似的问题here

作为一个副节点,您可能不应该更新watch表达式函数内的任何内容。在dataTypeValue上设置一个单独的监视功能会更有意义,它会更新placeholderText上的$scope属性并通过html placeholder <绑定<input type="text" ng-model="inputText" placeholder="{{placeholderText}}" />属性/ em>的