繁体   English   中英

指令未加载范围变量

[英]Directive isn't loading scope variable

所以我有一个非常简单的指令,应该执行一个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>

仅在$ http调用之后设置'currentJob'变量,但是div仅在填充后才显示。 日志返回scope.rating的“ null”,但是,如果我自己记录“ scope”,则它清楚地表明已按预期填充了“ rating”属性。

另外,如果我只是为'rating'属性输入一个硬编码的数字,则该指令将按预期工作。

我不确定自己在哪里出问题了吗? 有任何想法吗?

本质上来说,问题在于,当您使用ng-show ,您的指令在从Ajax检索到您的star值之前barrating加载到DOM树中,该指令已处理并barratingstar值为0 DOM。 基本上ng-show所做的是,它只是通过在DOM上切换display css属性来在html上隐藏或显示DOM。

因此,您可以有两种选择来使星形组件正常工作。

  1. 使用ng-if代替ng-show
  2. 在组件内使用$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); }); } 
  3. 您可以将两者结合使用。 仅当您使用ng-if和进行评级时,才显示评级,然后$watch将注意评级的任何更改以更新barrating元素。

更改指令以响应等级更改:

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属性定义的Angular Expression的更改,并适当地更新了barrating插件。


更新

我确实考虑过要使用手表,但对为什么我的原始设置不起作用感到好奇。

原始设置无效,因为在指令初始化时它只能设置一次星级。 由于指令初始化后数据从服务器到达,因此插件无法看到新数据。 通过使用手表,每次控制器更改变量(包括从服务器到达值的时间)时,设置都会更新。

还要注意,另一个答案将手表硬连线到特定的作用域变量(不明智)。 使用属性声明特定范围变量是更明智的。 它使指令更加通用。

当指令缺少使用AngularJS绑定的模板时,最好避免使用孤立范围 如本例所示,将手表直接放在属性上。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM