【问题标题】:attrs.$set in scope.$watch function keeps directive busyattrs.$set in scope.$watch 函数使指令保持忙碌
【发布时间】:2014-10-17 16:14:24
【问题描述】:

我在下面的 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 之外,代码运行良好。初步调查显示默认开关盒中的 attrs.$set 使其保持运行。结果是浏览器被冻结。

您能否指出,我如何使 scope.$watch 与 attrs.$set 在指令中一起工作?

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

【问题讨论】:

  • 尝试使用类似:var unwatch = scope.$watch 并在你完成工作时在 $watch 块内调用 unwatch()

标签: angularjs angularjs-directive angularjs-scope


【解决方案1】:

这似乎是由于当您设置placeholder 值时,IE 触发了input 事件。

您可以在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 上有一个单独的监视函数会更有意义,它会更新$scope 上的placeholderText 属性并通过html 绑定placeholder 属性<input type="text" ng-model="inputText" placeholder="{{placeholderText}}" />

【讨论】:

  • 嗨@miensol,感谢您指出IE问题和解决方案。是的,这成功了。我附议你的旁注。理想情况下,它应该只这样写。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-25
  • 1970-01-01
  • 1970-01-01
  • 2018-11-04
  • 2017-04-08
  • 1970-01-01
相关资源
最近更新 更多