【问题标题】:DOM elements not getting updated from angular controllerDOM 元素没有从角度控制器更新
【发布时间】:2017-02-15 03:01:34
【问题描述】:

我正在尝试在ng-blur 上运行一个函数,该函数将根据为该字段定义的regular expression 验证用户输入。

我想要实现的是,如果正则表达式与用户输入不匹配,我想将那个特定的文本字段输入框边框变成红色。

我知道这是一个简单的 JavaScript 案例,我们使用 getElementById() and modify DOM。我无法从常规控制器更新 DOM。

我不能使用 ng-messages 等,因为我想根据哪个正则表达式失败从控制器中抛出错误,所以我不能编写硬编码 ng-messages

任何有关如何进一步进行的见解都会非常有帮助。

代码: prop 对象:这将从 Salesforce 服务器中检索。我正在提供解释代码所需的内容。实际的响应需要大量的预处理,以便在运行时生成包含所有引用、查找字段、从服务器提取的选项列表选项等的表单。

[ 
 { label      : Application Name
   cid        : uniqueId
   typeApex   : CURRENCY
   fieldPath  : application_Name__c
   type       : NUMBER
   value      : ''
   dbRequired : true
   isRequired : false
 },
 {...similar array of JSON object ...},
 {}
]

view.html

<div ng-if="prop.type != 'picklist' && prop.type != 'reference'">
    <label for="{{prop.label}}">{{prop.label}}</label>
    <input type="{{prop.type}}" id="inputFields{!cid}" ng-blur='fieldValidation(prop.fieldPath, prop.typeApex, inputFields{!cid}, $event)' ng-model-options="{updateOn: 'blur'}"  
           class="form-control" name="{{prop.fieldPath}}" ng-model="fieldPathValue[prop.fieldPath]" ng-init="fieldPathValue[prop.fieldPath]=getDefaultValue(prop.type,prop.value)"
           ng-required="isRequired({{prop.dbRequired}}, {{prop.isRequired}})"/>
</div>

控制器:

从这里我尝试在出错时更新输入文本框的 DOM 元素

$scope.fieldValidation = function(fieldPath, type, id, $event) {

   // Hardcoded regular expression for testing, this will be read  from server object
    var myMap = new Map();
    myMap.set("Term__c","^[0-9]+$");
    myMap.set("Loan_Amount__c","[0-9]+(\.[0-9][0-9]?)?");

    var value = $event.target.value; //$event object contains element Id, user input value
    var reg = new RegExp(myMap.get(fieldPath));

    if(!reg.test(value)) {
       //add error message class to selected field
       //display error message on top of field

       $timeout(function(){
         // added $scope.apply recently, not a good practice I understand 
         $scope.$apply(function () {
           $scope.spanId = document.getElementById($event.srcElement.id);
           $scope.spanId.style.borderColor='#ff0000';
           $scope.spanId.style.border='solid';
           }); 
         }, 1000);
        }

【问题讨论】:

    标签: javascript html angularjs dom


    【解决方案1】:

    首先不需要在 $timeout 中使用 $apply,因为它在内部使用它。最佳实践,Dom Manipulations 不应该存在于控制器、服务或其他任何地方,而是存在于指令中。

    .directive('fieldvalidate', [
      function() {
        return {
          restrict: 'A',
          link: function($scope, $element, $attributes) {
            $element[0].onblur = function() {
              //check against regex
              if(){//if failed
                $element[0].style.borderColor='red';
                $element[0].insertAdjacentHTML('afterend', '<div>your message</div>');
              }
            }
          }
        };
      }
    ]);
    

    【讨论】:

    • 是的。我知道 $apply 不应该使用它,因为它会污染空间。我读过一篇用上述风格写的文章,所以尝试了一下。感谢它在一些额外的修改后工作得很好,因为我的正则表达式将根据加载哪个控制器从服务器加载。我在运行时加载控制器。不过我有一个疑问,如果正则表达式失败,我想在编辑器前面显示正则表达式失败的消息。我怎样才能做到这一点。我不想用每个输入字段对ng-messages 进行硬编码。
    • 谢谢我用 ng-message 不费吹灰之力就能做到这一点
    • btw afterend 是标准令牌吗?
    • 知道了。谢谢。
    猜你喜欢
    • 2014-01-03
    • 1970-01-01
    • 1970-01-01
    • 2015-07-28
    • 2018-10-21
    • 2015-09-06
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    相关资源
    最近更新 更多