Директива AngularJS приписывает многократное использование - PullRequest
0 голосов
/ 04 июня 2018

У меня есть следующий HTML:

<my-dom attri="something 01">content 01</my-dom>
<my-dom attri="something 02">content 02</my-dom>
<my-dom attri="something 03">content 03</my-dom>

И теперь я хочу, чтобы это во время выполнения было заменено на:

<div>something 01: content 01</div>
<div>something 02: content 02</div>
<div>something 03: content 03</div>

Поэтому я создал эту директиву AngularJS:

app.directive('myDom', function() {
    var content;

    return {
        restrict: 'EA',
        replace: true,

        scope : true,
        // scope : false,
        // scope: {},

        template: function(elem, attr){
            content = elem.clone();
            return '<div>{{myContent}}: {{oldContent}}</div>';
        },

        controller: function(){
        },
        link: {
            pre: function(scope, elem, attr){
                scope.myContent = content.attr("attri"); // could also use "attr"
                scope.oldContent= content.html(); // could not use "elem" or "attr"
            },
            post: function(scope, elem, attr){
            },
        }
    };
});

Здесь я сначала клонирую исходный элемент DOM в закрытой переменной «content», а затем заменяю элемент DOM новым.В этот новый HTML-тег я вставляю данные атрибута из старого кода.Но здесь все перепутано:

Выходной код:

<div>something 03: content 03</div>
<div>something 03: content 03</div>
<div>something 03: content 03</div>

Так что с областью видимости что-то не так.Но что?
Из документации scope : true создает новую область действия для директивы, наследуя родительскую область.
Изменения в родительской области влияют на область действия директивы, но изменения в области действия директивы НЕ изменяютродительская область.

Единственное, что я могу себе представить:
Эта одна директива имеет только одну область применения.Таким образом, все три использования <my-dom> имеют одну и ту же область действия.
Это правильно?И как мне добиться желаемого результата?

1 Ответ

0 голосов
/ 04 июня 2018

Как я уже упоминал в своем комментарии, ваш content распределяется между всеми экземплярами директивы, поэтому он перезаписывается в каждой функции шаблона.

Для достижения желаемого поведения вы можете использовать transcludeFn вместе с transclude: true для доступа к элементу, который был упакован вашей директивой, см. Пример ниже:

angular.module('plunker', [])
    .controller('MainCtrl', function ($scope) {

    })
    .directive('myDom', function () {
        return {
            restrict: 'EA',
            replace: true,
            transclude: true,
            scope: true,
            template: '<div>{{myContent}}: {{oldContent}}</div>',
            controller: function () {
            },
            link: {
                pre: function (scope, elem, attr, ctrl, transclude) {
                    transclude(function (clone) {
                        scope.myContent = attr["attri"];
                        scope.oldContent = clone.text();
                    });
                }
            }
        };
    });
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js"></script>
<body ng-app="plunker">

    <div ng-controller="MainCtrl">
        <my-dom attri="something 01">content 01</my-dom>
        <my-dom attri="something 02">content 02</my-dom>
        <my-dom attri="something 03">content 03</my-dom>
    </div>

</body>

Еще несколько интересных ответов и примеров в этом ТАКОМ вопросе .

...