隔离范围和角度指令中的“替换:true”的问题

Joe*_*Joe 6 angularjs angularjs-directive

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

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

  1. 我删除了ng-if指令。
  2. 或者,我删除了指令定义对象中的“替换”键。

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

我真的很想了解这里到底发生了什么,并感谢您的任何解释。

指令定义

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>'
    };
});
Run Code Online (Sandbox Code Playgroud)

输出(注意未添加任何警告危险类)

<!-- 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>
Run Code Online (Sandbox Code Playgroud)

删除替换后添加了alert-danger类(删除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>
Run Code Online (Sandbox Code Playgroud)

Est*_*ask 5

诚实的工作是ng-if克隆原始元素并赋予其继承的范围。它为此使用了包含,因此可以ng-if在具有隔离范围的元素上获取继承的范围,从而避免判决$compile:multidir错误Multiple directives requesting new/isolated scope

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

因此,它只是severitypageMessages父范围获取值,ng-class如果不存在,则将表达式评估为空字符串。

解决方案是不要ng-if在带有replace标志的指令的根元素上使用。replace标志具有弃用状态,这意味着问题不会得到解决。当指令的模板得到一个额外的<div>包装时(尽管它可能违背的目的replace),那么一切都应按预期进行。