Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs $compile之后的ng类奇怪行为_Angularjs_Angularjs Directive_Ng Class - Fatal编程技术网

Angularjs $compile之后的ng类奇怪行为

Angularjs $compile之后的ng类奇怪行为,angularjs,angularjs-directive,ng-class,Angularjs,Angularjs Directive,Ng Class,我已作出以下指示: (function () { 'use strict'; angular .module('app.widgets') .directive('zzForminput', formInput); function formInput($compile) { // Usage: // <div zz-forminput></div> fu

我已作出以下指示:

(function () {
    'use strict';

    angular
        .module('app.widgets')
        .directive('zzForminput', formInput);

    function formInput($compile) {
        // Usage:
        //     <div zz-forminput></div>

        function setupDom(element) {
            var input = element.querySelector("input, textarea, select");
            var type = input.getAttribute("type");
            var name = input.getAttribute("name");
            if (type !== "checkbox" && type !== "radio") {
                input.classList.add("form-control");
            }
            var label = element.querySelector("label");
            label.classList.add("control-label");

            element.classList.add("form-group");
            return name;
        }

        function addNgClass(form, element, name, $compile, scope) {
            var isExistingNgClass = element[0].attributes["data-ng-class"] || element[0].attributes["ng-class"];
            if (!isExistingNgClass) {
                var ngClass = "{'has-error':" + form.$name + "." + name + ".$invalid && " +
                                "(" + form.$name + "." + name + ".$dirty || vm.submit), " +
                                "'has-success':" + form.$name + "." + name + ".$valid && " +
                                form.$name + "." + name + ".$dirty}";
                element.attr("data-ng-class", ngClass);
                $compile(element)(scope);
            }
        }

        function link($compile) {
            return function (scope, element, attrs, form) {
                var name = setupDom(element[0]);

                addNgClass(form, element, name, $compile, scope);
            }
        }

        return {
            restrict: 'A',
            require: '^form',
            link: link($compile)
        }
    }

}());
(函数(){
"严格使用",;
有棱角的
.module('app.widgets')
.指令(“zzForminput”,formInput);
函数formInput($compile){
//用法:
//     
函数setupDom(元素){
var input=element.querySelector(“input,textarea,select”);
var type=input.getAttribute(“type”);
var name=input.getAttribute(“name”);
如果(键入!=“复选框”&&type!=“无线电”){
input.classList.add(“表单控件”);
}
var label=element.querySelector(“label”);
label.classList.add(“控制标签”);
元素.classList.add(“表单组”);
返回名称;
}
函数addNgClass(表单、元素、名称、$compile、范围){
var isExistingNgClass=元素[0]。属性[“数据ng类”]| |元素[0]。属性[“ng类”];
如果(!IsExistingClass){
var ngClass=“{'has-error':“+form.$name+”+name+“$invalid&&”+
“(“+form.$name+”+name+“$dirty | | vm.submit),”+
“'has-success':“+form.$name+”+name+“$valid&&”+
表格.$name+“+name+”$dirty}”;
元素属性(“数据ng类”,ngClass);
$compile(元素)(范围);
}
}
函数链接($compile){
返回函数(范围、元素、属性、形式){
var name=setupDom(元素[0]);
addNgClass(表单、元素、名称、$compile、范围);
}
}
返回{
限制:“A”,
要求:“^form”,
链接:链接($compile)
}
}
}());
我将该指令用作:

<div zz-forminput>
   <label for="firstName" class="col-md-4">First Name*</label>
   <div class="col-md-8">
       <input type="text" name="firstName" id="firstName" data-ng-model="vm.userDetails.firstName" required data-ng-maxlength="100">
   </div>
</div>

名字*
Angular成功编译标记。当我在输入字段中输入任何文本时,has success不会添加到div。但是当我清除文本框时,has success类将应用到div。现在,当我在输入字段中输入一些文本时,has success将应用到div


请为我提供此问题的解决方案

您之所以看到这种奇怪的行为,是因为您如何处理承载指令的元素的内容

发生的情况是,内容(包括输入上的
ng model
指令)被编译两次:一次是在Angular经过DOM时(在编译阶段),一次是在手动调用
$compile
服务时(在指令的链接阶段)。这会导致
ng model
指令以相同的名称向父窗体控制器注册两次,长话短说会导致一些奇怪的情况

处理内容的正确方法是使用指令的
link
功能提供的
transclude
功能

transclude: true,
link: function(scope, element, attrs, ctrls, transclude){
   transclude(scope, function(clone){
     element.append(clone); // clone is the clone of the contents, prebound to scope
   }
}
或者,简单地说,通过模板使用
,因为您不需要在那里做任何特殊的事情

transclude: true,
template: '<div ng-transclude></div>`
而且不需要
$compile
transclude

link: function(scope, element, attrs, formCtrl){
  var inputName = setupDom(element[0]);

  scope.$watch(function(){
    return formCtrl[inputName].$valid && formCtrl[inputName].$dirty;
  }, function(v){
    if (v) element.addClass("has-success");
    else element.removeClass("has-success");
  });

  scope.$watch(function(){
    return formCtrl[inputName].$invalid && 
           (formCtrl[inputName].$dirty || formCtrl.$submitted);
  }, function(v){
    if (v) element.addClass("has-error");
    else element.removeClass("has-error");
  })
}