问题
I am using introJS to have a user guide. I can show various features, however, i want to add a directive to the markup e.g:
$scope.IntroOptions = {
steps: [
{
element: "#step1",
intro: "Click the button: <button my-directive>Test Directive</button>",
position: 'left'
}
],
With the above, i can see the text 'Click the button' plus a default button.
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];
However, with the above. The console.log
is never displayed, yet when i inspect the markup, i can see:
<button my-directive>Test Directive</button>
If i place the directive any where else in my application, the console.log
is successful.
回答1:
Maybe this can help you.
I've tried to implement @S.Klechkovski's solution here, it failed for me. But let anyone experiment with this.
But actually, I've made something you want 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'
}]
};
}
(the hint is to use ng-intro-onAfterChange
to compile there using proper scope)
The bad part is that I've hard-coded the template there.
But you can go further and set the template as an attribute of the element you want to show tooltip on. Had no possibility to access intro
field of a step. So... Sory for that extreme level of coding pornography here (it seems to be working):
Full 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'
}]
};
}
Full 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>
Note: here is the scary tip that you might need to wrap the code inside the onIntroAfterChange
with $timeout
. Hope you won't need it
PS: Actually the problem is that we are using IntroJS from AngularJS. Libs have completely different approaches, so mixing them is a pain.
PPS: Hope someone could provide better solution than I did.
PPS: The best solution is too rewrite introJS using Angular directives
回答2:
Directives are activated when Angular compiles the HTML templates. In this case you need to manually compile the template using the $compile service. Example:
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'
}
]
};
回答3:
I bet that the button isn't getting compiled by the angular directive. If you put a breakpoint on the line "element.bind('click', function() {" it would never be hit. Can you post more of the code so that we can determine the best way to make it load?
来源:https://stackoverflow.com/questions/37055468/introjs-add-directive-to-step-markup