【问题标题】:$watch doesn't work if I specify a scope outside the link function如果我在链接函数之外指定范围,$watch 不起作用
【发布时间】:2014-06-09 17:09:56
【问题描述】:

我刚开始开发一个使用 flot 绘制一堆数据的 Angular 应用程序。它适用于静态数据,但是一旦我们将指令连接到 mongo,我必须按照教程here 让它用于更新数据。由于一个特定的原因,我度过了一段地狱般的时光:

这是我的指令 HTML:

<div class="panel-body" data-ng-controller="flotChartCtrl">
  <div data-flot-line-chart data-data="revenueData.data" data-options="line1.options" style="width: 100%; height: 300px;"></div>
</div>

和javascript:

.directive("flotLineChart", [
    function () {
        return{
            restrict: 'A',
            scope: {
                data: "=",
                options: "="
            },
            link: function(scope, elem, attrs){
                var chart = null;
                // var options = { ... };

                scope.$watch('data', function(data, oldData) {
                    if(!chart) {
                        chart = $.plot(elem, data, options);
                        elem.show();
                    } else {
                        chart.setData(data);
                        chart.setupGrid();
                        chart.draw();
                    }
                });
            }
        };
    }
])

正如您在 html 中看到的,我使用 data-options 属性将 line1.options 对象传递到指令中。当我只使用静态数据而不使用ng-model$watch 函数时,这有效并且scope: { options: "=" } 分配是正确的。但是,似乎每当我在link 之外的范围内设置anything 时,它都会破坏$watch$watch 总是收到一个未定义的 data... 而我的 scope.options 也是未定义的。在$watch 函数之外scope.options 是正确的,但是如果在实际绘制数据时我不能使用它们,那对我没有多大帮助。

我不得不对link: 中的选项进行硬编码并注释掉外部范围分配。我需要创建一堆不同的图表,所有这些图表看起来都不一样。我讨厌不得不为每个选项硬编码不同的选项,但目前我没有看到任何其他方式来完成这项工作。有什么方法可以让我从 $watch 函数中的 HTML 访问我的其他数据属性,而不会破坏一切?

注意:我试过attrs.options,但这只是给了我一个“line1.options”字符串,而不是实际的对象。

编辑1:

根据 ExpertSystem 的建议更新了我的代码。不再使用ng-modelscope 在 $watch 中仍然不可用:

【问题讨论】:

  • 避免未来困难的提示:RTFM(并确保您使用UTFM):)
  • 相信我,我正在阅读手册,但我没有找到我必须寻找的答案(或者如果我找到它们,我显然不理解它们)。不幸的是,我仍然很难过,所以如果你有解决方案而不是明显的评论,我很乐意听到。
  • 我在发布解决方案后发表了评论 :)
  • 抱歉,没注意名字。以为是别人:)

标签: javascript angularjs


【解决方案1】:

您的指令应如下所示:

...
restrict: 'A',
scope: {
    data:    '=ngModel',
    options: '='
},
link: function(scope, elem, attrs){
    ...
    scope.$watch('data', function(newValue, oldValue) {
        ...

尽管在这里使用ngModel 似乎是多余的。


This fiddle 证明scope 确实在$watch 回调中定义。

【讨论】:

  • 这解决了我在 $watch 中使用 scope.data 的问题,但是 $watch 中仍然不存在 scope,这意味着我无法访问 $ 中的 scope.options看……这是我的主要问题。
  • scope$watch 回调中绝对可用。请发布您的确切代码(scope 未定义)。
  • 这是我的确切代码。它告诉我范围没有定义。
  • 愚蠢地意识到虽然scope$watch 中可能不可用,但在父链接函数中声明的变量 可用的,并且scope 在那里,所以我我只是分配var options = scope.options,这在我的$watch 中有效。感谢您的帮助。
  • 在发布的代码中仍然没有scope的任何引用。我很高兴您找到了解决方法,但 scope$watch 回调中可用(因为它是在父函数中定义的)。也许您使用的是options,而不是scope.options
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-05
  • 2012-02-27
  • 1970-01-01
相关资源
最近更新 更多