【问题标题】:Not able to access angular directive's isolated scope无法访问角度指令的隔离范围
【发布时间】:2018-11-01 15:06:47
【问题描述】:

第一条指令:

app.directive("myDirectiveOne", function($rootScope){
    return {
        templateUrl : "/custom-one-html.html",
        restrict: "AE", 
        replace:true,
        scope: {
            somedata: "=",
            flags: "=",
            functionone: "&"
        }
        ,controller: function($rootScope,$scope, $element) {
           $scope.firstFunction = function(){
                console.log("First function is getting called")
           }
$scope.$on('firstBroadcast',function(event, data){
                $rootScope.$broadcast('secondBroadcast', data)
            });

    }

第二条指令:

app.directive("myDirectiveTwo", function($rootScope){
    return {
        templateUrl : "/custom-two-html.html",
        restrict: "AE", 
        replace:true,
        scope: {
            data: "=",
            functiontwo: "&"
        }
        ,controller: function($rootScope,$scope, $element) {
           $scope.secondFunction = function(){
                console.log("Second function is getting called")
                $rootScope.$broadcast('firstBroadcast', {})
           }
$scope.$on('secondBroadcast',function(event, data){
                $scope.callSomeFunctionWithData(data);
            });
$scope.secondFunction();

    $scope.editFunction = function(x){
console.log("This is the edit function", x);
        }

父控制器:

$scope.parentFuntion = function(){
        console.log("No trouble in calling this function")
}

所以,问题是当我尝试从myDirectiveTwo html 模板调用函数时,处于活动状态的控制器是父控制器,而不是孤立的控制器。

可能与我使用的广播有关?

HTML代码:

<div ng-repeat="x in data">
    <h5>{{x.name}}</h5>
    <button ng-click="editFunction(x)">Edit</button>
</div>

奇怪的是我得到了数据值并且 ng-repeat 在加载时工作正常。但是,当我单击按钮时,它什么也没做。如果我在父控制器中添加相同的功能,它会被调用.. :( 如何使隔离范围控制器再次处于活动状态..?

【问题讨论】:

  • 没有什么明显的错误,您能否也粘贴一些 HTML 或复制问题的 JSFiddle?谢谢
  • @Protozoid 添加了 html 代码。

标签: angularjs angularjs-directive angularjs-scope angular-controller angular-broadcast


【解决方案1】:

问题是我使用了已弃用的方法replace:true。这导致了意想不到的场景。正如@Protozoid 所建议的那样,我查看了他的链接并发现了问题。引用官方文档:

When the replace template has a directive at the root node that uses transclude: element, e.g. ngIf or ngRepeat, the DOM structure or scope inheritance can be incorrect. See the following issues: Incorrect scope on replaced element: #9837 Different DOM between template and templateUrl: #10612

删除了replace:true,现在它很好:)

这是链接: Here

【讨论】:

    【解决方案2】:

    问题是 ng-repeat 创建了一个子作用域,因此 editFunction 最终位于父作用域上。

    来自文档

    ...每个模板实例都有自己的范围,其中给定的循环变量设置为当前集合项...

    Docs here

    您可以通过获取按钮元素的范围并检查 $parent 来验证这是否是问题所在,例如 angular.element(document.getElementsByTagName("button")).scope()

    尽管考虑到 代码气味,您可以将 $parent 附加到您的函数调用以访问它,但请记住,这现在会依赖您的 HTML 结构。

    &lt;button ng-click="$parent.editFunction(x)"&gt;Edit&lt;/button&gt;

    【讨论】:

    • 好的.. 不应该有办法在指令的情况下处理父范围吗?我的意思是这是否意味着我不能在指令中使用 ng-repeat 并使隔离范围控制器处于活动状态?应该有一些解决方法..
    • 好吧,通常认为在作用域上绑定所有内容是不好的做法,因为它会变成 作用域汤 ...相反,您应该尝试使用 controllerAs 语法和 @987654327 @in 指令。 Docs here
    • 非常感谢 :) 问题是我使用了已弃用的方法 replace:true。这导致了意想不到的情况。正如@Protozoid 所建议的那样,我查看了他的链接并发现了问题。引用官方文档:When the replace template has a directive at the root node that uses transclude: element, e.g. ngIf or ngRepeat, the DOM structure or scope inheritance can be incorrect. See the following issues: Incorrect scope on replaced element: #9837 Different DOM between template and templateUrl: #10612 我删除了replace:true,现在它很好:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多