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
,我认为它会起作用,只是我希望能够更新名为propertyscope[attrs.maskValue]
——不起作用,因为我需要执行ssn:“
以及所有其他可能的值!使用带有=
属性的隔离作用域可以完全满足您的需要。你为什么说它不起作用?你能提供一个Plunker/jsFiddle脚本吗?@MichaelBenford我会设置一个=
无法正常工作,因为它将更新控制器中的maskValue
(该值不存在)。例如,我可以做ssn:“=”
,但是我依赖于一个特定的值。我希望能够更新属性transparently@MichaelBenford您可以看到这是有效的:--这是我使用隔离作用域以一种更具角度性的方式(我认为)进行的尝试。它不起作用:也许是这个@阿康苏:我以前看过这段视频,但对这种特殊情况没有帮助。如果我在指令中执行了scope.ssn
,我认为它会起作用,只是我希望能够更新名为propertyscope[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();
});
}
};
});