Как использовать сервис $ compile для включения данных HTML с директивами AngularJS - PullRequest
0 голосов
/ 14 сентября 2018

У меня есть контроллер, который загружает контент в области контента с помощью 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 ]

0 голосов
/ 15 сентября 2018

Служба $ compile создает объект jqLite , который необходимо добавить в DOM с помощью метода jqLite или 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>

Вместо этого используйте пользовательскую директиву для компиляции и добавления данных 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Руководство разработчика - HTML-компилятор .

0 голосов
/ 14 сентября 2018

Используйте директиву.

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

Кеш шаблонов будет управляться автоматически.

...