函数从未在AngularJS指令控制器中调用

时间:2016-04-20 11:33:49

标签: angularjs

我面临一个奇怪的情况,我已经创建了一个指令,控制器连接到该指令,控制器的两个微小功能之一永远不会从视图中调用,而另一个函数是。

这是the plunker

我期待的信息是(粗体是不显示的信息)

  

您仅限于:监狱

我已经创建了数十个指令,无论是以它们自己的权利还是作为GitHub上现有指令的包装器,从轻量级指令,如自定义选择到角度ui-grid等庞然大物。

我在这里结束了为什么{{getArea()}}在视图中根本没有产生任何文字。我仔细检查了代码,尝试用新的眼睛来做,可以这么说,我没有看错。我已经在Eclipse中为这一小段代码创建了一个特定的项目,安装了Wampserver,这样我就可以在Firebug中设置断点了,上帝知道我必须走多远才能让我能够理解它的错误。我写的代码。

例如,在isRestricted()中,我可以毫无问题地致电getArea()。但是,Angular似乎没有从指令中找到该函数。

已经提出了一些类似的问题,但没有错误(缺少控制器或ng-app规范,缺少模块声明中的依赖列表,嵌套控制器等)似乎要应用。这显然是一个值得学习的重要课程,我真的很想学习它。

编辑:吸取的教训是ng-if创建新范围。新的范围介于控制器和指令之间,这导致指令的模板失去对控制器中定义的任何内容的访问权限(至少,我将如何表达它)。 (注意,评论暗示指示优先权。)

有几种解决方案,它们都维护模板访问控制器中定义的功能所需的原型继承:

  • 不使用隔离范围
  • 没有在我的指令的顶级元素上定义ng-if指令,因为这会导致冲突(在我的控制器范围和ng-if定义的范围之间)。我相信ng-if在这里获胜,这导致控制器的范围超出了指令的范围。在子div上使用ng-if可以解决问题(因为这样,ng-if范围继承了我的控制器的范围,因此使模板可以使用这些函数)。

由于此指令需要CSS样式,我使用了scope: false

4 个答案:

答案 0 :(得分:2)

<span class="scoop-badge-content">{{$parent.getArea()}}</span>
指令中的

scope:true

这是因为ng-if使用自己的范围

奇怪的是,当我遇到这个问题时,我通常使用点符号。但它在这里不起作用,可能是因为我们在一个指令中,直到现在我都没有这个案例。

编辑:执行此操作模板的最后一种方法:

  <div class="scoop-badge scoop-badge-ua">
    <div  ng-if="isRestricted()">
        <span class="scoop-badge-title">You are limited to:</span>
        <span class="scoop-badge-content">{{getArea()}}</span>
    </div>
</div>

我认为这项工作是因为你已经替换了true和ng-if会与ng-scope发生冲突,如果它在顶级DOM元素上。

答案 1 :(得分:1)

当您的指令中有scope = {}时,Angular会创建一个隔离的范围。这意味着它无法进入getArea()功能。

您可以完全删除scope = {}行,或将其设置为scope = truescope = false,具体取决于您之后尝试实现的目标。

当设置为scope = true时,Angular将创建一个新的范围对象并将其分配给指令。此范围对象原型继承自其父范围。

当设置为scope = false时,指令将使用其父作用域。 (这是默认值。如果删除此行,则效果相同。)

有关范围here

的更多信息

答案 2 :(得分:0)

从指令定义中删除范围:{}解决了问题。

    app.directive('scoopBadgeUa', function() {

        return {
            restrict : "A",
            scope: {}, // This is not needed, creates conflict
            templateUrl : "scoop-badge-ua.html",
            replace : true,
            controller : 'ScoopBadgeUaController',
        };
    });

答案 3 :(得分:0)

您的代码是正确的,除了在 scoop-badge-ua.html 中添加<div> <div class="scoop-badge scoop-badge-ua" ng-class="{'visible': isRestricted()}" ng-if="isRestricted()"> <span class="scoop-badge-title">You are limited to:</span> <span class="scoop-badge-content">{{getArea()}}</span> </div> </div> 代码之外,您无需做任何其他事情。

transclude: true

enter image description here

我比x={ 0:{ start:"2016-01-01", values:[10,11,12], names:["a","b","c"] }, 1:{ start:"2016-01-02", values:[25,23,50], names:["a","b","c"] } } for(y in x){ if(x.hasOwnProperty(y)){ x[y].names.forEach((key, i) => x[y][key] = x[y].values[i]); delete x[y].names; delete x[y].values; } } console.log(x);更喜欢这个解决方案,因为它不包含html代码中的指令标记,最终转换为更清晰的代码。