Javascript 使用AngularJS中的解析器和格式化程序在指令模板中执行双向绑定时出现的问题
我很难弄清楚如何在AngularJS中为指令创建一个模板内的元素的双向绑定 我的例子是: HTMLJavascript 使用AngularJS中的解析器和格式化程序在指令模板中执行双向绑定时出现的问题,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我很难弄清楚如何在AngularJS中为指令创建一个模板内的元素的双向绑定 我的例子是: HTML {{myValue}} Javascript var-app=angular.module('app',[]); 函数AppCtrl($scope){ $scope.myValue='Hello World'; }; app.directive('大写',function()){ 返回{ 限制:'E', 替换:正确, 要求:'ngModel', 模板:“”,//如果我删除包装div,它会工作,
{{myValue}}
Javascript
var-app=angular.module('app',[]);
函数AppCtrl($scope){
$scope.myValue='Hello World';
};
app.directive('大写',function()){
返回{
限制:'E',
替换:正确,
要求:'ngModel',
模板:“”,//如果我删除包装div,它会工作,但我必须将指令范围上的ng model属性更改为其他属性,例如“model”
范围:{
ngModel:“=”,
},
链接:功能(范围、元素、属性、模型){
函数parse(string){//模板函数中的div永远不会被调用
//警报(“解析”);
//调试器;
返回(字符串| |“”).toLowerCase();
}
函数格式(string){//在模板中使用div时,string总是“未定义”的,函数只调用一次
//警报(“格式化”);
//调试器;
return(字符串| |“”).toUpperCase();
}
ngModel.$parsers.push(解析);
ngModel.$formatters.push(格式);
}
};
});
问题是双向绑定已经建立,但是解析器和格式化程序没有被正确调用。传递给这些函数的值总是“未定义”。如果我要绑定到的元素是模板中最外层的元素,但我需要绑定到子元素,那么我的示例将起作用
我想我已经把它缩小到了一个问题,就是链接函数中的ngModel参数是什么。我对指令不是很熟悉,所以我甚至不确定ngModel对象在该上下文中是什么
如有任何帮助,我们将不胜感激。
作为使用ng模型指令修改元素的属性,这种指令工作得更好。这可以让你摆脱所有的模板
<div ng-app="App">
<div ng-controller="AppCtrl">
<input ng-model="myValue" />{{myValue}}
<input uppercase ng-model="myValue" />
</div>
</div>
{{myValue}}
此指令根本不需要模板。甚至没有隔离范围。我们也遇到了同样的问题。不幸的是,我无法摆脱模板(我确实需要一个嵌套的输入元素)。除了去掉模板之外,你还解决过这个问题吗?我尝试过类似的方法,但我的原始问题(为了简单起见,我将其归结为问题中给定的代码),需要一个更复杂的模板,其中包含几个元素,我想用这些元素替换指令元素。我会将该指令拆分为两个:输入修饰符,然后使用另一个指令创建代码块。或者只使用内置的include指令:。需要注意的一点是,include创建了一个新的作用域,因此我必须将您的模型变量移动到一个对象中,以便它可以从子作用域写入。Ok。我想我明白你的意思了。你的小提琴看起来不错,但如果我输入模板输入,普通输入不会更新,任何进一步输入到普通输入中的操作都不会再更新模板中的输入。我可以通过将其拆分为两个指令使其工作:一个用于复杂模板的元素指令和一个用于使用格式化程序和解析器增强输入的属性指令。我现在很难使元素上的其他属性对嵌套属性指令可见,但是如果我不能弄清楚的话,这可能是另一个问题。在调用嵌套属性指令的link函数之前,似乎没有绑定元素指令模板中的{{}}表达式。在本例中,“name”属性直到我在链接函数中需要它之后才被绑定。
var app = angular.module('App', []);
function AppCtrl($scope) {
$scope.myValue = 'Hello World';
};
app.directive('uppercase', function() {
return {
restrict : 'E',
replace: true,
require: 'ngModel',
template: '<div><input ng-model="ngModel" /></div>', //If I remove the wrapping div, it works, but I have to change the ng-model attribute on the directive scope to be something else, such as 'model'
scope: {
ngModel: '=',
},
link: function(scope, element, attr, ngModel) {
function parse(string) { //with the div in the template function is never called
//alert('parsing');
//debugger;
return (string || '').toLowerCase();
}
function format(string) { //with the div in the template, string is always 'undefined' and the function is only called once
//alert('formatting');
//debugger;
return (string || '').toUpperCase();
}
ngModel.$parsers.push(parse);
ngModel.$formatters.push(format);
}
};
});
<div ng-app="App">
<div ng-controller="AppCtrl">
<input ng-model="myValue" />{{myValue}}
<input uppercase ng-model="myValue" />
</div>
</div>