4

Я использую introJS для получения руководства пользователя. Я могу показать различные функции, однако, я хочу, чтобы добавить директиву разметки например:IntroJS Добавить директиву на разметку шага

$scope.IntroOptions = { 
    steps: [ 
     { 
      element: "#step1", 
      intro: "Click the button: <button my-directive>Test Directive</button>", 
      position: 'left' 
     } 
    ], 

С выше, я могу видеть текст «Нажмите кнопку» плюс кнопку по умолчанию.

myDirective.js

var myDirective = function() { 
     return { 
      restrict: 'A', 
      link: function(scope, element, attrs) { 
       element.bind('click', function() { 
        console.log('you clicked the directive'); 
       }); 
      } 
     }; 
    }; 

return [myDirective]; 

Однако, с выше. console.log никогда не отображается, но когда я проверить разметку, я могу увидеть:

<button my-directive>Test Directive</button> 

Если я эту директиву где-либо еще в моем приложении, console.log успешна.

+0

Можете ли вы поместить это в Codepen, пожалуйста? –

ответ

0

Директивы активируются, когда Angular компилирует HTML-шаблоны. В этом случае вам нужно вручную скомпилировать шаблон, используя команду $ compile. Пример:

var elementToString = function (element) { 
    var container = angular.element('p').append(angular.element(element)); 
    return container.html(); 
} 

var introTemplate = 'Click the button: <button my-directive>Test Directive</button>'; 
var introContent = $compile(introTemplate)($scope); 

$scope.IntroOptions = { 
    steps: [ 
     { 
      element: "#step1", 
      intro: elementToString(introContent), 
      position: 'left' 
     } 
    ] 
}; 
+0

спасибо, но как вы используете компиляцию $ в контроллере? $ Scope.IntroOptions является defiend в Angular Controllers. –

+1

$ compile - это сервис, который также можно вводить в контроллеры, но если вы будете следовать лучшим практикам, директива. –

+0

Спасибо за информацию. Если вы можете предоставить пример компиляции $, используемой в контроллере, я буду рад принять. И этим я не имею в виду контроллер в рамках директивы. –

1

Возможно, это может вам помочь.

Я попытался реализовать решение @ S.Klechkovski here, это провалилось для меня. Но пусть кто-нибудь экспериментирует с этим.

Но на самом деле, я сделал то, что вы хотите here:

function appCtrl($scope, $compile) { 

    function onIntroAfterChange(targetElement, scope) { 

    angular.element(document.querySelector(".introjs-tooltiptext")) 
     .append($compile(
      angular.element(
      "<button my-directive>Test Directive</button>")) 
     (scope)).html() 
    } 

    $scope.onIntroAfterChange = onIntroAfterChange; 

    $scope.IntroOptions = { 
    steps: [{ 
     element: "#step1", 
     intro: "Click the button:", 
     position: 'bottom' 
    }] 
    }; 
} 

(подсказка, чтобы использовать ng-intro-onAfterChange компилировать там с помощью надлежащего охвата) Плохая часть является то, что я жестко кодируется шаблон там.

Но вы можете пойти дальше и установить шаблон как атрибут элемента, который вы хотите отобразить всплывающую подсказку. Не было возможности получить доступ к intro полем шага. Так что ... Сори для этого экстремального уровня кодирования порнографии here (это, кажется, работает):

Полный JS:

angular.module("app", ["angular-intro"]) 
    .directive("myDirective", myDirective) 
    .controller("appController", appCtrl); 

function myDirective() { 
    return { 
    restrict: 'A', 
    link: function(scope, element, attrs) { 
     element.bind('click', function() { 
     console.log('you clicked the directive'); 
     }); 
    } 
    }; 
}; 



function appCtrl($scope, $compile) { 

    function onIntroAfterChange(targetElement, scope) { 
    angular.element(document.querySelector(".introjs-tooltiptext")) 
     .append($compile(
      angular.element(targetElement).attr("data-template")) 
     (scope)).html() 
    } 

    $scope.onIntroAfterChange = onIntroAfterChange; 

    $scope.IntroOptions = { 
    steps: [{ 
     element: "#step1", 
     intro: "Click the button:", 
     position: 'bottom' 
    }] 
    }; 
} 

Полный HTML

<body ng-app="app" ng-controller="appController"> 
    <div ng-intro-options="IntroOptions" ng-intro-autostart="true" ng-intro-onafterchange="onIntroAfterChange"> 
    <p id="step1" data-template="<button my-directive>Test Directive</button>"> 
     Text 
    </p> 
    <button my-directive>Test Directive</button> 

Примечание: here - это страшный совет, который вам может понадобиться для обертывания кода внутри onIntroAfterChange с помощью $timeout. Надеюсь, он вам не понадобится

PS: На самом деле проблема в том, что мы используем IntroJS от AngularJS. У Libs есть совершенно разные подходы, поэтому их смешивание - это боль.

PPS: Надеюсь, что кто-то может обеспечить лучшее решение, чем я.

PPS: Лучшее решение слишком переписать introJS используя угловые директивы

0

Я держал пари, что кнопка не получает составитель угловой директивы. Если вы поместите контрольную точку в элемент «строка».bind ('click', function() {" он никогда не пострадает. Можете ли вы опубликовать больше кода, чтобы мы могли определить, как это сделать?