代码之家  ›  专栏  ›  技术社区  ›  Paul

如何使用$compile服务包含带有AngularJS指令的HTML数据

  •  1
  • Paul  · 技术社区  · 7 年前

    我有一个控制器,它使用ng repeat将内容填充到内容区域。问题是有些内容需要放在模板文件前面,因此需要“动态”编译。现在我有一个动态添加内容的函数:

    $scope.layouts = [
    
        { id: 'Dashboard', icon: 'dashboard', view: '/qph/views/Dashboard.php' },
        { id: 'Customers', icon: 'people', view: '/qph/views/users.php' },
        { id: 'Quotes', icon: 'format_list_bulleted', view: '/qph/views/Quotes.php' }
    
    ];
    
    $scope.workspace = {};    
    
    var getTemplate = function(id){
    
        var view = 'test.php';
    
        $timeout(function() { //added timeout
    
        if($templateCache.get(view) === undefined) {
                $templateRequest(view).then(function (data) {
                    $scope.workspaces.forEach(function (v) {
                        if (v.id == id) v.content = $compile(data)($scope);
                    });
                });
    
        } else {
            $scope.workspaces.forEach(function (v) {
                if (v.id == id) v.content = $compile($templateCache.get(view))($scope);
            });
    
        }
        }, 2000);
    };
    
    $scope.workspaces =
        [
            { id: 1, name: "Dashboard", icon: 'dashboard', active:true  }
        ];
    getTemplate(1);
    

    我已经检查了数据变量是否具有预期的html内容,但是编译输出了以下内容:

    {"0":{"jQuery331075208394539601512":{"$scope":"$SCOPE","$ngControllerController":{}}},"length":1}
    

    有人知道为什么它没有按照预期编译html内容吗?

    以下是模板内容供参考:

    <div class="col-sm-6 col-sm-offset-3" ng-controller="UserController">
    <div class="col-sm-6 col-sm-offset-3">
        <div class="well">
            <h3>Users</h3>
            <button class="btn btn-primary" style="margin-bottom: 10px" ng-click="user.getUsers()">Get Users!</button>
            <ul class="list-group" ng-if="user.users">
                <li class="list-group-item" ng-repeat="user in user.users">
                    <h4>{{user.name}}</h4>
                    <h5>{{user.email}}</h5>
                </li>
            </ul>
            <div class="alert alert-danger" ng-if="user.error">
                <strong>There was an error: </strong> {{user.error.error}}
                <br>Please go back and login again
            </div>
        </div>
    </div>
    </div>
    

    以下是用于显示已编译内容的选项卡视图:

    <ul class="nav nav-tabs workspace-tabs">
        <li class="nav-item" ng-repeat="space in workspaces">
            <a class="nav-link" data-toggle="tab" href="#workspace{{space.id}}" ng-class="(space.active == true ) ? 'active show': ''">
                <span class="hidden-sm-up"><i class="material-icons md-24">{{space.icon}}</i></span>
                <span class="hidden-xs-down">{{space.name}}</span>
                <button ng-click="workspace.remove($index)">x</button>
            </a>
        </li>
    </ul>
    
    <div class="tab-content workspace-content">
        <div ng-repeat="space in workspaces" id="workspace{{space.id}}" class="tab-pane fade in" ng-class="(space.active == true ) ? 'active show': ''">
            {{space.content}}
        </div>
    </div>
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   georgeawg    7 年前

    这个 $compile 服务创建 jqLite jqLite or jQuery append() 方法。使用插值 {{ }} 只会呈现 jqLite

    <div class="tab-content workspace-content">
        <div ng-repeat="space in workspaces" id="workspace{{space.id}}" class="tab-pane fade in" ng-class="(space.active == true ) ? 'active show': ''">
            ̶{̶{̶s̶p̶a̶c̶e̶.̶c̶o̶n̶t̶e̶n̶t̶}̶}̶
            <compile html="space.html"></compile>
        </div>
    </div>
    

    相反,使用 custom directive 要编译HTML数据并将其附加到DOM中,请执行以下操作:

    app.directive("compile", function($compile) {
        return {
            link: postLink,
        };
        function postLink(scope, elem, attrs) {
            var rawHTML = scope.$eval(attrs.html)
            var linkFn = $compile(rawHTML);
            var $html = linkFn(scope);
            elem.append($html);
        }
    })
    

    有关详细信息,请参阅 AngularJS Developer Guide - HTML Compiler .

        2
  •  2
  •   georgeawg    7 年前

    app.directive('myCustomer', function() {
      return {
        templateUrl: 'test.php',
        controller: 'UserController'
      };
    })
    

    模板缓存将自动管理。