Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/405.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
Javascript 在指令中使用控制器属性/方法_Javascript_Angularjs_Angularjs Directive - Fatal编程技术网

Javascript 在指令中使用控制器属性/方法

Javascript 在指令中使用控制器属性/方法,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我有各种输入(包括稍后解释的指令),例如: 最后,maskValue指令: app.directive("maskValue", function () { return function (scope, element, attrs) { /* does some focus/blur magic and string replacement */ scope[attrs.maskValue] = this.value; scope[at

我有各种输入(包括稍后解释的指令),例如:

最后,
maskValue
指令:

app.directive("maskValue", function () {
    return function (scope, element, attrs) {
        /* does some focus/blur magic and string replacement */
        scope[attrs.maskValue] = this.value;
        scope[attrs.validate]();
    };
});
这是可行的,但对我来说,这似乎是对Angular的滥用。相反,使用隔离作用域更有意义,如:

    scope: {validate: "&"}
然后我可以使用
scope.validate()
而不是
scope[attrs.validate]()
。但是,对于隔离作用域,我无法更新控制器中的相应值。使用
{maskValue:“=”}
不起作用,因为这将尝试更新父级的
maskValue
属性,而不是特定值。我认为使用
{ssn:“=”}
会起作用,但是我必须更新控制器的特定属性,而不是将其设置为指令属性,这会使指令不灵活。显然,也不建议使用
$parent

如何在隔离范围指令内动态访问控制器的属性

  • 示例工作代码:
  • 我试图达到的目标(不起作用):

编辑:我不能在输入上使用
ng model=ssn
等,因为在
mask value
中的聚焦/模糊事件期间,输入的实际值发生了更改。例如,它可能会变成
******####
,但我需要存储实际值
#########
,而控制器似乎是合适的位置,因为控制器稍后会出于其他原因使用它。

我很抱歉,但为什么不这样做:

app = angular.module("foo", []);

app.controller("Ctrl", ['$scope', function ($scope) {
    $scope.ssn = "";
    $scope.validate = function () { console.log($scope.ssn); };
}]);

app.directive("maskValue", function () {
    return {
        link: function (scope, element, attrs) {
            element.bind("change", function () {  
                scope.validate();
            });
        },
    };
});
HTML是这样的:

<div ng-app=foo>
    <div ng-controller=Ctrl>
        <input ng-model="ssn" mask-value />
    </div>
</div>

我很抱歉,但为什么不这么做:

app = angular.module("foo", []);

app.controller("Ctrl", ['$scope', function ($scope) {
    $scope.ssn = "";
    $scope.validate = function () { console.log($scope.ssn); };
}]);

app.directive("maskValue", function () {
    return {
        link: function (scope, element, attrs) {
            element.bind("change", function () {  
                scope.validate();
            });
        },
    };
});
HTML是这样的:

<div ng-app=foo>
    <div ng-controller=Ctrl>
        <input ng-model="ssn" mask-value />
    </div>
</div>

我知道您已经得到了问题的答案,但我认为值得一提的是,由于您似乎正在进行一些验证,您可以使用Angular的内置功能来进行验证,并且仍然能够使用
ng model
。下面是一个例子:

app.directive("maskValue", function ($parse) {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function (scope, element, attrs, ngModel) {
      if (!ngModel) return;
      var validator = $parse(attrs.validator)(scope);

      ngModel.$render = function() {
        var hasFocus = document.activeElement == element[0];
        if (ngModel.$valid || hasFocus) element.val(ngModel.$modelValue)
        else element.val('#######');
      };

      element.bind('blur', function() {
        ngModel.$setValidity('maskValue', validator(this.value))
        ngModel.$render();
      });

      element.bind('focus', function() {
        ngModel.$render();
      });
    }
  };
});

此指令使用,以便与
ng model
一起控制视图的更新方式。在这个精心设计的示例中,当元素失去焦点并且验证函数返回false时,它将简单地渲染。但是当控件再次聚焦时,它将呈现其真实值,以便用户可以更改它。请注意,绑定到控件的作用域的属性保持不变,而其视图会根据元素状态(有效或无效)进行相应更改。您可以看到一个工作示例。

我知道您已经得到了问题的答案,但我认为值得一提的是,由于您似乎正在进行一些验证,您可以使用Angular的内置功能来进行验证,并且仍然能够使用
ng model
。下面是一个例子:

app.directive("maskValue", function ($parse) {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function (scope, element, attrs, ngModel) {
      if (!ngModel) return;
      var validator = $parse(attrs.validator)(scope);

      ngModel.$render = function() {
        var hasFocus = document.activeElement == element[0];
        if (ngModel.$valid || hasFocus) element.val(ngModel.$modelValue)
        else element.val('#######');
      };

      element.bind('blur', function() {
        ngModel.$setValidity('maskValue', validator(this.value))
        ngModel.$render();
      });

      element.bind('focus', function() {
        ngModel.$render();
      });
    }
  };
});

此指令使用,以便与
ng model
一起控制视图的更新方式。在这个精心设计的示例中,当元素失去焦点并且验证函数返回false时,它将简单地渲染。但是当控件再次聚焦时,它将呈现其真实值,以便用户可以更改它。请注意,绑定到控件的作用域的属性保持不变,而其视图会根据元素状态(有效或无效)进行相应更改。您可以看到一个工作示例。

使用带有
=
属性的隔离作用域完全满足您的需要。你为什么说它不起作用?你能提供一个Plunker/jsFiddle脚本吗?@MichaelBenford我会设置一个
=
无法正常工作,因为它将更新控制器中的
maskValue
(该值不存在)。例如,我可以做
ssn:“=”
,但是我依赖于一个特定的值。我希望能够更新属性transparently@MichaelBenford您可以看到这是有效的:--这是我使用隔离作用域以一种更具角度性的方式(我认为)进行的尝试。它不起作用:也许是这个@阿康苏:我以前看过这段视频,但对这种特殊情况没有帮助。如果我在指令中执行了
scope.ssn
,我认为它会起作用,只是我希望能够更新名为property
scope[attrs.maskValue]
——不起作用,因为我需要执行
ssn:“
以及所有其他可能的值!使用带有
=
属性的隔离作用域可以完全满足您的需要。你为什么说它不起作用?你能提供一个Plunker/jsFiddle脚本吗?@MichaelBenford我会设置一个
=
无法正常工作,因为它将更新控制器中的
maskValue
(该值不存在)。例如,我可以做
ssn:“=”
,但是我依赖于一个特定的值。我希望能够更新属性transparently@MichaelBenford您可以看到这是有效的:--这是我使用隔离作用域以一种更具角度性的方式(我认为)进行的尝试。它不起作用:也许是这个@阿康苏:我以前看过这段视频,但对这种特殊情况没有帮助。如果我在指令中执行了
scope.ssn
,我认为它会起作用,只是我希望能够更新名为property
scope[attrs.maskValue]
——不起作用,因为我需要执行
ssn:“
以及所有其他可能的值!这确实有效!我有点不明白为什么。我猜
=
采用属性值而不是属性名称来更新到父级。不过它很完美:)根据文档,
=
与父作用域的模型建立了双向绑定。唯一的问题是,在事件处理程序中,您需要调用
$apply
,以便它知道如何更新绑定。我必须在
.validate()
之后调用
作用域。$apply()
,因为
.validate()
更新控制器的作用域(特别是它设置了
$scope.error
。任何方法都可以更新控制器的作用域
app.directive("maskValue", function ($parse) {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function (scope, element, attrs, ngModel) {
      if (!ngModel) return;
      var validator = $parse(attrs.validator)(scope);

      ngModel.$render = function() {
        var hasFocus = document.activeElement == element[0];
        if (ngModel.$valid || hasFocus) element.val(ngModel.$modelValue)
        else element.val('#######');
      };

      element.bind('blur', function() {
        ngModel.$setValidity('maskValue', validator(this.value))
        ngModel.$render();
      });

      element.bind('focus', function() {
        ngModel.$render();
      });
    }
  };
});