Reputation: 2979
I have an <iframe>
element that I want to be created only when user clicks a button. Being new to angular, I just placed it into the page and added ng-if
directive binding element presence to some boolean in my model. It works as expected with exception that for the brief moment before the page fully loads and angular runs the element is created. In fact I can see the outgoing request to load the frame in my browser's F12 tools.
What is the proper Angular approach to create the element only upon user request? I realize I can change frame's src
, but wondering if there's more elegant solution.
Here's full page code:
<!doctype html>
<html>
<body ng-app="bomberApp" ng-controller="MooCtrl">
<button ng-click="showFrame()">Click!</button><br>
<iframe src="//xkcd.com" ng-if="show" ng-init="show=false"></iframe>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.js"></script>
<script>
var bomberApp = angular.module('bomberApp', []);
bomberApp.controller("MooCtrl", function($scope) {
$scope.showFrame = function(){
$scope.show = !$scope.show;
}
});
</script>
</body>
</html>
Upvotes: 1
Views: 366
Reputation: 524
You can make a custom directive and create the iframe when the button is clicked just using plain JavaScript DOM functions.
angular.module('testApp', [])
.directive('generateIframe', function() {
return {
restrict: 'E',
template: '<div><button ng-click="vm.create()">{{vm.message}}</button><br><div id="iframe-container"></div></div>',
scope: {
src: '@'
},
controller: function($scope) {
var vm = this;
vm.src = $scope.src;
vm.iframeCreated = false;
vm.message = 'Create';
vm.create = function() {
var iframeContainer = document.getElementById('iframe-container');
if (!vm.iframeCreated) {
var iframe = document.createElement('iframe');
iframe.src = vm.src;
iframe.class = 'some-class'; // add it if you need to style it
iframe.id = 'created-iframe';
iframeContainer.appendChild(iframe);
vm.iframeCreated = true;
vm.message = 'Remove';
} else {
var iframe = document.getElementById('created-iframe');
iframeContainer.removeChild(iframe);
vm.iframeCreated = false;
vm.message = 'Create';
}
}
},
controllerAs: 'vm'
}
});
Upvotes: 3
Reputation: 6200
The problem comes from the rendering order of the page:
Your iframe is there before the <script>
tag which loads Angular!
Go ahead, utilize your <head>
area to load the scripts, and you will find that once Angular is loaded before the iFrame, it will not show:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.js"></script>
<script>
var bomberApp = angular.module('bomberApp', []);
bomberApp.controller("MooCtrl", function($scope) {
$scope.showFrame = function() {
$scope.show = !$scope.show;
}
});
</script>
</head>
<body ng-app="bomberApp" ng-controller="MooCtrl">
<button ng-click="showFrame()">Show me the Money!</button>
<br>
<iframe src="//xkcd.com" ng-if="show" ng-init="show=false"></iframe>
</body>
</html>
Upvotes: 3