html file as cellTemplate not working in directive compile: or pre: function - angularjs-directive

Before i came here, i did read through this thread: https://github.com/angular-ui/ui-grid/issues/2078, but still didn't find the solution.
Pretty similar issue:
angular.module('XXX')
directive(
'myDirective', [function() {
return {
restrict: 'E',
scope: {data: '='},
templateUrl: 'myTemplate.html',
compile: function() {
return {
pre: function(scope, elem) {
var cT = '<div>Details</div>';
scope.gridOptions = {
columnDefs: [{ field: 'myField', displayName:
'myFieldName', cellTemplate: 'myCellTemplate.html'}]
};
}
}
}
}]);
I copied exactly in cT to 'myCellTemplate.html' and tried to load it, not working, but if i use the inline cT it's working fine. I tired to change 'myTemplate.html' to 'myCellTemplate.html' in templateUrl: to see if directive can successfully load the html, and it was actually also working. So i'm wondering does compile: -> pre: function have a different path so it couldn't find 'myCellTemplate.html' in its current path?
Any thoughts?
Update
Worked after i changed the path to '/partial/.../myCellTemplate.html'

Worked after i changed the path to '/partial/.../myCellTemplate.html'

Related

How to get console output using Polymer?

I have this part of code inside dom-module tag:
<script>
Polymer({
is: "hi-world",
properties:{
name: {
type: String,
value: "default";
},
edad: {
type: Number;
},
created: function(){
console.log("The element was created")
console.log(this)
console.log(this.$)
console.log(this.$.title);
}
}
})
</script>
But when I execute the code, nothing happens in console at Chrome, Firefox or even (sorry about this) IE. What am I doing wrong? I see some guide lines at https://www.polymer-project.org/1.0/docs/devguide/registering-elements, but it doesn't work.
Also, I tried with one line console.log, with:
created: function(){
console.log("The element was created");
}
And, again, no results in web browser console.
EDIT 1:
According to a1626, the code would be, actually the solution:
<script>
Polymer({
is: "hi-world",
properties:{
name: {
type: String,
value: "default";
},
edad: {
type: Number;
}
},
created: function(){
console.log("The element was created")
console.log(this)
console.log(this.$)
//console.log(this.$.title) <-- commented, it collapses with created method
}
})
</script>
You have placed created callback inside the properties object. And during created callback elements are not prepared so you won't find using this.$.id

Directive with js-call in the template - method does not get called

In my angular app, I have an alert-service, which handles the list of alerts. I then have a directive, which renders all the alerts to the page. I use the UI Bootstrap components.
However, the close button of the alert does not call the method:
.directive('someAlert', ['alertService', function (alertService){
var templateString = '<uib-alert ng-repeat="alert in vm.alerts" type="{{alert.type}}" close="closeAlert($index)">{{alert.msg}}</uib-alert>';
return {
restrict: 'E',
template: templateString,
scope: true,
controller: function(){
var vm = this;
vm.alerts = alertService.get();
vm.closeAlert = function (index) {
console.log('closeAlert within directive controller called');
alertService.closeAlertIdx(index);
}
},
controllerAs: 'vm',
replace: true
}
}]);
Try this in the templateString
close="vm.closeAlert($index)"
I added a close method directly to the alert-instance. Then the alert.close() is working as expected. Nice solution found: alertservice and a slightly modified

angularjs directives - how to add interpolated attribute

From what I can tell, an interpolated value string expands/resolves correctly if it's specified in the template, but not if it's added later. To demonstrate, I have the following code:
describe.only('directive tests - ', function() {
it('add dynamic interpolated attribute value', function() {
module(function($compileProvider) {
$compileProvider.directive('hello', function() {
return {
restrict: 'A',
replace: true,
template: '<a foo="{{1+1}}"></a>',
compile: function link(tElement, tAttrs) {
tElement.attr('bar', '{{2+2}}'); // add an interpolated attr.
}
};
});
});
inject(function($compile, $rootScope) {
var element = angular.element('<div hello/>');
$compile(element)($rootScope);
$rootScope.$apply();
console.log(' * ', element.prop('outerHTML'));
});
});
});
and console.log prints:
<a foo="2" hello="" bar="{{2+2}}" class="ng-scope"></a>'
and NOT:
<a foo="2" hello="" bar="4" class="ng-scope"></a>'
as I'd think. What gives?
tElement.attr('bar', $interpolate('{{2+2}}')());
Right, it is too late to do this in compile, more specifically to make changes to the directive element itself that have to be compiled (it needs to be recompiled in order to make the changes work).
But the following
// replace: true,
template: '<a foo="{{1+1}}">aa</a>',
compile: function link(tElement, tAttrs) {
tElement.find('a').attr('bar', '{{2+2}}');
}
would work as expected.
Attribute watching and interpolation can also be done in link (or controller):
link: function (scope, element, attrs) {
attrs.$observe('bar', function (interpolatedBar) {
scope.bar = interpolatedBar;
});
}
It will set up a watcher on bar attribute (while $interpolate(...)() is one-time assignment and doesn't interpolate any values from scope).

Set angular directive attribute by calling function

I'm trying to set the value of a directive's attribute by calling a function on the containing page's controller, but it doesn't work as expected. In the code below, the "make" object does not have a "modelList" property, so I must place a separate call to the server to get it for each make.
<div ng-repeat="make in makeList">
<model-list-directive model-list="getModelList(make)" />
</div>
app.controller("myController",function($scope) {
$scope.getModelList = function(make) {
return null;
//return myService.getModelList(make);
};
})
app.directive("modelListDirective",function() {
restrict:'E',
scope: {
modelList: '='
},
template: '<ul><li ng-repeat="model in modelList">{{model.modelName}}</li></ul>',
controller: ['$scope', function ($scope) {
}]
If the getModelList() function is set to return null (not commented out in the code), no error is given, but the function is called multiple times (randomly varies between 3 and 5 usually).
The real problem comes when I invoke myService.getModelList(make) (commented out in the code). This results in an endless loop of calls to the service, which crashes the browser.
I'm guessing this is because of two-way binding, but I'm not sure.
Is there a better way to get dynamic data to the directive?
I think part of the problem is that your directive definition isn't returning an object. It should look like this:
app.directive('modelListDirective',function() {
return { // <-- need to return an object
restrict:'E',
scope: {
modelList: '='
},
template: '<ul><li ng-repeat="model in modelList">{{model.modelName}}</li></ul>',
controller: ['$scope', function ($scope) {
}]
};
});
However, you're passing a function as a 2-way binding into the directive, which you shouldn't do. See this answer to a similar issue.
What you can do instead is inject myService directly into your directive, then have your directive call myService.getModelList() in its link function.
So your markup would look like this:
<div ng-repeat="make in makeList">
<model-list-directive make="{{make}}" />
</div>
Each directive instance would just need the make.
And your directive definition would look like this:
app.directive('modelListDirective', ['myService', function(myService) {
return {
restrict:'E',
scope: {
make: '#'
},
link: function (scope, element, attrs) {
scope.modelList = myService.getModelList(scope.make);
},
template: '<ul><li ng-repeat="model in modelList">{{model.modelName}}</li></ul>',
controller: ['$scope', function ($scope) {
}]
};
}]);
setting scope.modelList in its link function.
Here's a fiddle.

Angular directive coming in JSON

I have a directive:
Here I am passing a data object:
<a-link options = "data"></a-link>
And here is my directive:
.directive('aLink', function() {
return {
restrict: 'AE',
replace: true,
template: '<a href = "{{href}}">{{text}}</div>',
link: function(scope, element, attrs) {
scope.$watch('options', function(newValue, oldValue) {
if (newValue)
scope.href = newValue.href;
scope.text = newValue.text;
});
}
});
This works fine. It gives me an anchor tag like
link
My question is:
If i get the following on json:
{
body : "Click <a-link text = 'here' href = '/home/login.html'></a-link>"
}
and my html:
<p ng-bind-html = "body"></p>
This doenot work.
How do I recompile this? Do I need to pass it through another directive and compile it there?
Use $compile service:
$compile(response.body)($scope)