Reputation: 2786
I have two buttons. When pressed it displays a modal, with som text. But I also want to add some html dynamically depending on which button is pressed.
I have tried both $observe
and $watch
methods, but I'm having problems making it work.
here is my code.
angular.module('TM', [])
.controller('protocolCtrl', function(){
this.text = 'Now looking at the protocol part';
this.modalId = 'protocolModal';
})
.controller('categoryCtrl', function(){
this.text = 'Now looking at the category part';
this.modalId = "categoryModal";
})
.directive('modalDirective', function(){
return {
restrict: 'E',
scope: {
ctrl: '=',
modalId: '@',
},
template: ['<div id="{{modalId}}" class="modal fade" role="dialog">',
'<div class="modal-dialog">',
'<div class="modal-content">',
'<div class="modal-header">',
'<h4 class="modal-title">Modal Header</h4>',
'</div>',
'<div class="modal-body">',
'<p> {{ ctrl.text }} </p>',
'</div>',
'<div class="modal-footer">',
'<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>',
'</div>',
'</div>',
'</div>',
'</div>'].join(''),
link: function(scope, element, attrs) {
element.$observe('modalId', function(){
var modal = element.find('#{{modalId}}');
if(modal == 'protocolModal'){
element.find('#{{modalId}}').append('<div>this is a protocol test...</div>');
} else {
element.find('#{{modalId}}').append('<div>this is a category test...</div>');
}
});
}
}
});
Upvotes: 0
Views: 540
Reputation: 9560
If your two DOM structure diverses, you can consider using two different templates depending on some parameter value.
templateUrl
can be specified as a function, such as:
angular.module('Joy', [])
.controller('ProfileCtrl', ['$scope', function ($scope) {
$scope.user = {
name: 'Elit'
};
}])
.directive('profile', [function () {
return {
restrict: 'A',
templateUrl: function (elem, attrs) {
return 'style-' + attrs.color + '.html';
}
};
}]);
And use the directive as:
<div ng-app="Joy" id="play-ground" ng-controller="ProfileCtrl">
<div profile color="red"></div>
<div profile color="green"></div>
</div>
In this case, if the color
is red
, the directive will load template from style-red.html
. Otherwise from style-green.html
.
In your case, you might maintain a flag in the outside controller. Clicking either button will change this flag value and pass in to the directive. The directive will load different templates accordingly.
Upvotes: 0
Reputation: 6322
See i updated your Fiddle
Use attr in link function. because you already given attribute to your html i.e: modal-id="{{pctrl.modalId}}
<modal-directive ctrl="pctrl" modal-id="{{pctrl.modalId}}"></modal-directive>
if(attrs.modalId == 'protocolModal'){
element.find('#{{modalId}}').append('<div>this is a protocol test...</div>');
} else {
element.find('#{{modalId}}').append('<div>this is a category test...</div>');
}
Edit :
use $timeout
$timeout(function () {
if (attrs.modalId == 'protocolModal') {
element.find('#' + attrs.modalId).append('<div>this is a protocol test...</div>');
} else {
element.find('#' + attrs.modalId).append('<div>this is a category test...</div>');
}
}, 1000)
Now why $timeout because you are applying template and and at same time your link function append your div so it will not apply your div .So first apply template and then in template append your div
And if you want to show that div in popup content the use this selector. see this example: https://jsfiddle.net/kevalbhatt18/o76hxj69/6/
element.find('#'+attrs.modalId +' .modal-body').append('<div>this is a protocol test...</div>');
Upvotes: 0
Reputation: 49590
I don't think there is element.$observe
- there is attrs.$observe
and scope.$watch
. You already have modelId
on the scope, so let's use that.
Also, instead of the wonky .find
by id, inject an element as a placeholder for the template and replaceWith
it accordingly:
template: '<div id="{{modalId}}">\
...\
<div class="modal-body">\
<template-placeholder></template-placeholder>\
</div>\
</div>",
link: function(scope, element){
// ...
var unwatch = scope.$watch("modalId", function(val){
var placeholder = element.find('template-placeholder');
if(val == 'protocolModal'){
placeholder.replaceWith('<div>this is a protocol test...</div>');
} else {
placeholder.replaceWith('<div>this is a category test...</div>');
}
unwatch(); // seems like you don't really need to set it again
}
}
Upvotes: 1