与孤立的范围和“替换:真实"有关的问题在角度指令 [英] Issue with isolated scope and "replace: true" in angular directive

查看:92
本文介绍了与孤立的范围和“替换:真实"有关的问题在角度指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用AngularJS进行错误消息指令时,我一直在努力解决范围问题.

I have been struggling with a scoping issue when making an error message directive using AngularJS.

我将ng-if和ng-class指令作为指令模板的一部分,但是ng-class指令中的表达式似乎总是返回空字符串,除非:

I have an ng-if and ng-class directive as part of the directive template, but the expression in the ng-class directive always seemed to return a blank string, unless:

  1. 我删除了ng-if指令.
  2. 或者,我在指令定义对象中删除了'replace'键.

查看我的指令的编译输出,如果删除ng-if或replace键,则好像正在创建一个隔离范围,但是如果它们都留在那,那么就没有ng-isolate-scope html输出中的类,只是ng-scope.

Looking at the compiled output for my directive, it looks like an isolated scope is being created if the ng-if or the replace key is removed, but if they are both left in, then there are no ng-isolate-scope classes in the html output, just ng-scope.

我真的很想确切地了解这里发生的事情,并感谢您做出任何解释.

I would really like to understand exactly what is going on here and would be grateful for any explanations.

指令定义

angular.module('myMessages')
.directive('pageMessages', function() {

    return {
        restrict: 'E',
        replace: true,
        scope: {
            messages: '='
        },
        controller: function($scope) {
            $scope.severity = 'alert-success';
        },
        template: '<div ng-if="messages.length > 0">' +
                    '<div class="alert" ng-class="severity">' + 
                        '<ul>' + 
                            '<li ng-repeat="m in messages">{{::m.message}}</li>' +
                        '</ul>' +
                    '</div>' +
                  '</div>'
    };
});

输出(请注意,未添加任何警报危险类)

<!-- ngIf: messages.length > 0 -->
<div ng-if="messages.length > 0" messages="messages" class="ng-scope">
    <div class="alert" ng-class="severity">
        <ul>
        <!-- ngRepeat: m in messages -->
            <li ng-repeat="m in messages" class="ng-binding ng-scope">test error</li>
        <!-- end ngRepeat: m in messages --></ul>
    </div>
</div>
<!-- end ngIf: messages.length > 0 --></div>

删除警告后添加了警告危险类(删除ng-if也可以)

<page-messages messages="messages" class="ng-isolate-scope">
    <!-- ngIf: messages.length > 0 -->
    <div ng-if="messages.length > 0" class="ng-scope">
        <div class="alert alert-danger" ng-class="severity">
            <ul>
            <!-- ngRepeat: m in messages -->
                <li ng-repeat="m in messages" class="ng-binding ng-scope">test error</li>
            <!-- end ngRepeat: m in messages -->
            </ul>
        </div>
    </div>
    <!-- end ngIf: messages.length > 0 -->
</page-messages>

推荐答案

诚实ng-if的工作是克隆原始元素并赋予其继承范围.它为此使用了包含,因此允许ng-if获取具有孤立范围的元素的继承范围,从而避免了$compile:multidir出错并带有Multiple directives requesting new/isolated scope判决.

The job of truthy ng-if comes to cloning an original element and giving it inherited scope. It uses transclusion for that, this allows ng-if to get inherited scope on an element with isolated scope, avoiding $compile:multidir error with Multiple directives requesting new/isolated scope verdict.

好处是,如果在具有独立作用域的元素上使用它,则不会引发错误.不好的事情是当在具有更高优先级(ng-if优先级为600)的指令上使用时,它将替换它,而忽略其范围.另一个不好的事情是,当在具有隔离范围的指令的根模板元素上使用时(像这样),它将仅用克隆的元素替换一个从父范围继承其范围的元素(属于指令的父元素,因为它是自己的)元素已被replace替换).

The good thing is that it won't throw an error if it is used on an element with isolated scope. The bad thing is when used on a directive with higher priority (ng-if priority is 600) it will just replace it, ignoring its scope. And another bad thing is that when used on on root template element of a directive with isolated scope (like this one) it will just replace an element with cloned one that inherits its scope from parent scope (belonging to directive's parent element, because its own element was already replaced with replace).

因此,它只是从pageMessages父作用域获取severity值,并且将ng-class表达式评估为空字符串(如果不存在).

So it just gets severity value from pageMessages parent scope and evaluates ng-class expression to empty string if it doesn't exist.

解决方案是不要在带有replace标志的指令的根元素上使用ng-if. replace标志问题不会得到解决.当指令的模板得到一个额外的<div>包装器(尽管它可能与replace的目的背道而驰)时,一切都应该按预期的方式工作.

The solution is to not use ng-if on root element of a directive with replace flag. replace flag has got deprecation status, which means that issues won't be fixed. When directive's template gets an extra <div> wrapper (though it may serve against the purpose of replace), everything should work as intended.

这篇关于与孤立的范围和“替换:真实"有关的问题在角度指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆