UPDATE1:开发了可以重现问题的plunker示例。见下文。
我的项目中有一个奇怪的问题,它只出现在一个地方。最后,我能够使用plunker样本重现问题:
http://plnkr.co/edit/JJbq54?p=preview
在上面的示例中,请参阅“使用ng-if”和“不使用ng-if”部分,在输入文本中输入内容,并查看双花括号如何在ng-if
下无效,但{ {1}}工作正常。此外,如果您从模板ng-bind
中删除check-if-required
,问题也就解决了。
我有以下HTML5代码块:
sites-and-improvements.html
我知道 <div ng-if="isFullCUSPAP" id="sites_and_imrpovements_comments">
<div class="form-row">
<div class="inputs-group">
<label>WIND TURBINE:</label>
<div class="input-binary">
<label>
<input type="radio" id="wind_turbine"
name="wind_turbine"
ng-model="$parent.wind_turbine"
value="Yes" force-model-update />
Yes
</label>
</div>
<div class="input-binary">
<label>
<input type="radio" id="wind_turbine"
name="wind_turbine"
ng-model="$parent.wind_turbine"
value="No" force-model-update />
No
</label>
</div>
<span ng-bind="wind_turbine"></span>
<span>wind_turbine = {{wind_turbine}}</span>
</div>
</div>
</div>
会创建一个新的子范围。请参阅上面的代码,范围变量ng-if
。仅在此HTML5文件中,大括号wind_trubine
不起作用。但是,如果我使用{{}}
,它可以正常工作。在其他HTML5文件中,我没有任何问题。这个HTML5使用指令实现如下:
ng-bind
而且,简单地说,我把它放在父母身上,如下所示:
app.directive('sitesAndImprovements', function() {
return {
restrict: 'E',
replace:true,
templateUrl: '<path-to-file>/site-and-improvments.html',
link: function (scope, elem, attrs) {
//Business Logic for Sites and Improvements
}
}
})
我能看到的唯一区别是,这个实现有两层嵌套<sites-and-improvements></sites-and-improvements>
,如下所示:
ng-if
根据评论,我使用了<div ng-if="some_expression">
...
...
<sites-and-improvements></sites-and-improvements>
...
...
</div>
符号并相应地定义了controller As
。请参阅下面的快照。如果MainController
与两个级别嵌套,则似乎存在问题。范围变量完全混淆。使用ng-if
和双花括号,我得不到相同的结果。
如果您检查上述快照,即使我使用了ng-bind
表示法,与使用controller As
进行插值相比,您会看到ng-bind
给出不同的结果。
我甚至在链接函数中将{{}}
的默认值更改为如下设置:
wind_turbine
我注意到在页面加载时,一切看起来都很好,但是当我使用鼠标更改输入元素scope.MainController.wind_turbine = 'Yes';
的值时,除了使用wind_trubine
的引用之外,所有相关引用都会正确更新。
也许这是因为{{}}
有两个嵌套级别?
感谢您的反馈。
塔雷克
答案 0 :(得分:2)
从replace: true
指令中删除sites-and-improvements
:
app.directive('sitesAndImprovements', function() {
return {
restrict: 'E',
̶r̶e̶p̶l̶a̶c̶e̶:̶t̶r̶u̶e̶,̶
templateUrl: 'site-and-improvments.html',
link: function (scope, elem, attrs) {
//debugger;
}
}
})
正在与check-if-required
指令作斗争:
app.directive('checkIfRequired', ['$compile', '$timeout', function ($compile, $timeout) {
return {
priority: 2000,
terminal: true,
link: function (scope, el, attrs) {
el.removeAttr('check-if-required');
$timeout(function(){
//debugger;
$(':input', el).each(function(key, child) {
if (child && child.id === 'test_me') {
angular.element(child).attr('ng-required', 'true');
}
if (child && child.id === 'testInput1') {
//debugger;
//angular.element(child).attr('ng-required', 'true');
}
});
$compile(el, null, 2000)(scope);
})
}
};
}])
replace:true
is Deprecated 来自文档:
replace
([已弃用!],将在下一个主要版本中删除 - 即v2.0)指定模板应替换的内容。默认为
false
。
true
- 模板将替换指令的元素。false
- 模板将替换指令元素的内容。
- AngularJS Comprehensive Directive API - replace
deprecated
来自GitHub:
Caitp--它被弃用了,因为
replace: true
存在已知的非常愚蠢的问题,其中一些问题无法以合理的方式得到解决。如果你小心并避免这些问题,那么对你有更多的权力,但为了新用户的利益,告诉他们更容易,这会让你头疼,不要这样做&#34;。
有关详细信息,请参阅Explain replace=true in Angular Directives (Deprecated)
答案 1 :(得分:0)
AngularJS团队发布的另一个解决方案:
https://github.com/angular/angular.js/issues/16140#issuecomment-319332063
基本上,他们建议将link()
函数转换为使用compile()
函数。这是更新代码:
app.directive('checkIfRequired', ['$compile', '$timeout', function ($compile, $timeout) {
return {
priority: 2000,
terminal: true,
compile: function (el, attrs) {
el.removeAttr('check-if-required');
var children = $(':input', el);
children.each(function(key, child) {
if (child && child.id === 'test_me') {
angular.element(child).attr('ng-required', 'true');
}
});
var compiled = $compile(el, null, 2000);
return function( scope ) {
compiled( scope );
};
}
};
}]).directive('sitesAndImprovements', function() {
return {
restrict: 'E',
replace:true,
templateUrl: 'site-and-improvments.html'
}
});
我对此解决方案的主要问题是我使用传递给scope
函数的link()
参数。例如,在上面的.each()
循环中,我需要使用{{<angular expre>}}
获取基于插值的元素ID的值。
因此,我尝试在pre-link
函数中使用post-link
和compile
,其中scope
可用。我注意到,执行在ng-if
时删除了带有pre-link
的部分,然后在此之后不久添加。因此,我必须使用$watch
来监视子项的更改,以便在需要时运行所需的过程。我开发了这个plunker样本:
http://plnkr.co/edit/lsJvhr?p=preview
即使经过所有这些努力,问题也未得到解决。因此,类似案例的底线是,如果您需要使用范围,则必须删除replace: true
。
任何反馈都将不胜感激。
塔雷克