ng-click в директиве кажется срабатывает только один раз - PullRequest
0 голосов
/ 19 июня 2019

Я пытаюсь реализовать директиву, заменяющую тег с помощью ng-click в нем.Вызов ng-click вызывает функцию, которая заменяет содержимое элемента div (всегда одинакового) содержимым другого элемента, идентификатор которого передается в качестве параметра.Мне удалось заставить его работать, но только для первого клика.После этого страница перезагружается, и это происходит потому, что ng-click не запускается, а (пустой) атрибут href имеет значение.

html-код:

  <!-- language: lang-html -->
  <div id="uiMain" class="container">
    Go to <go target="block01">01</go>, <go target="block02">02</go> or <go target="block03">03</go>
  </div>
  <div id="block01" class="block">
    Go to <go target="block02">02</go> or <go target="block03">03</go>
  </div>
  <div id="block02" class="block">
    Go to <go target="block01">01</go> or <go target="block03">03</go>
  </div>
  <div id="block03" class="block">
    Go to <go target="block01">01</go> or <go target="block02">02</go>
  </div>

и моя директива:

.directive('go', function() {
    return {
        restrict: "E",
        scope: {
            target: "@"
        },
        transclude: true,
        template: '<a href="" ng-click="displayBlock(\'{target}\')"><ng-transclude></ng-transclude></a>',
        link: function (scope, element, attrs) {
            scope.displayBlock = function() {
                // Get the content of the target block
                var content = angular.element(document.querySelector("#"+attrs.target));
                // Get the main container
                var mainContainer = angular.element(document.querySelector("#uiMain"));
                // then replace the link with it
                if (content !== null) { 
                    //mainContainer.html($compile(content.innerHTML)($scope)); 
                    mainContainer.html(content.html()); 
                }
            };
        }
    };
});

Я попытался вернуть свою функцию обратно в контроллер, но его поведение такое же.Я также попытался использовать $ compile или $ apply, чтобы убедиться, что область актуальна с вставленным html-содержимым: это не работает, потому что директивы в моем целевом блоке уже скомпилированы.

Вотмой plnkr для всего кода.

Я хочу иметь возможность щелкать ссылки, чтобы переходить назад и вперед, но сейчас есть кое-что, что мешает ng-click запускать больше, чемодин раз.


РЕДАКТИРОВАТЬ: благодаря Mosh-Feu мне удалось заставить его работать, добавив ng-non-bindable ко всем целевым элементам и изменив мою директиву следующим образом:

.directive('go', function($compile) {
return {
    restrict: "E",
    scope: true,
    transclude: true,
    template: '<a href="" ng-click="displayBlock(\'{target}\')"><ng-transclude></ng-transclude></a>',
    link: function (scope, element, attrs) {
        scope.displayBlock = function() {
            // Get the content of the target block
            var content = angular.element(document.querySelector("#"+attrs.target));
            // Get the main container
            var mainContainer = angular.element(document.querySelector("#uiMain"));
            // then replace the link with it
            if (content != null) { 
                mainContainer.html(content.html()); 
                $compile(mainContainer)(scope);
            };
        };
    }
};

});

Но решение Aditya Bhave чище, поэтому я буду его использовать.Большое спасибо, ребята!

1 Ответ

0 голосов
/ 20 июня 2019

Проблема в том, что когда мы заменяем innerHTML div на html (), он не компилируется как код angularjs. Правильный способ - использовать ng-шаблоны.

Взгляните на этого Планкра - http://next.plnkr.co/edit/x0TiUkka5nJwqB8K

  1. Я использую div с атрибутом ng-include, изначально установленным в шаблон mainBlock.html.
  2. Событие On Click изменяет URL шаблона родительского контроллера.

Примечание. У нас может быть более понятный код, если мы передадим temmplateURL в качестве атрибута директиве, а затем изменим его в onclick вместо использования scope. $ Parent.

...