所以我有一个非常简单的指令,它应该执行一个jquery插件函数:
angular.module('myproject.directives').directive('starRating', function () {
return {
restrict: 'A',
scope: {
rating: '='
},
link: function (scope, elem, attr) {
console.log('rating', scope.rating);
elem.barrating({
theme: 'css-stars',
readonly: true
});
elem.barrating('set', scope.rating);
}
};
});
这是HTML:
<select class="service-rating"
ng-show="!!currentJob.Review.ServiceRating"
star-rating rating="currentJob.Review.ServiceRating">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
'currentJob'变量仅在$ http调用后设置,但div仅在填充后才设置为显示。对于scope.rating,日志返回'null',但是如果我自己记录'scope',它会清楚地显示按预期填充的'rating'属性。
此外,如果我只输入'rating'属性的硬编码数字,该指令将按预期工作。
我不确定我在哪里错了?有什么想法吗?
答案 0 :(得分:2)
基本上问题是,当您使用ng-show
时,您的指令会在从star
检索到的Ajax
值之前加载到DOM树中,它会被处理并barrating
1}}附加到star
值0
的DOM。基本上ng-show
的作用是,它只是通过在DOM上切换display
css属性来隐藏或显示html上的DOM。
因此,您可以使用两个选项来使星形组件正常工作。
ng-if
代替ng-show
在组件中使用$watch
来更新star
评级(这将是一个很好的解决方案)。
link: function (scope, elem, attr) {
console.log('rating', scope.rating);
elem.barrating({
theme: 'css-stars',
readonly: true
});
scope.$watch('star', function(newValue){
elem.barrating('set', newValue);
});
}
ng-if
&amp;进行评分时显示评分然后$watch
会对barrating
元素上的任何更改进行更新。答案 1 :(得分:1)
更改指令以对评级中的更改作出反应:
app.directive('starRating', function () {
return {
restrict: 'A',
scope: false,
link: function (scope, elem, attr) {
elem.barrating({
theme: 'css-stars',
readonly: true
});
scope.$watch(attr.rating, function (newValue) {
elem.barrating('set', newValue);
console.log('rating', newValue);
});
}
};
});
以这种方式编码,在每个摘要周期,观察者检查rating
属性定义的角度表达式的更改,并相应地更新barrating
插件。
我确实想过使用手表,但我很好奇为什么我的原始设置不起作用。
原始设置不起作用,因为它在指令初始化时仅设置星级评分一次。由于数据在指令初始化后从服务器到达,因此插件不会看到新数据。通过使用手表,每次控制器更改变量时设置都会更新,包括值从服务器到达的时间。
另请注意,另一个答案将手表硬连线到特定的范围变量(不明智)。使用属性声明特定范围变量更明智。它是一个更通用的指令。
当指令缺少使用AngularJS绑定的模板时,避免隔离范围更明智。将手表直接放在属性上,如本例所示。