I have a custom directive I have created that loads a template into a modal window. The modal window is a template itself and is able to run my custom directive without issues. That template that is loaded into the modal contains another directive which creates a select list using angular-selectize. Here is my directive:
var dynamicTemplate = function($templateRequest, $compile) {
return {
restrict: "E",
link: function(scope, element, attrs) {
var modalOptions = JSON.parse(attrs.modalOptions);
$templateRequest(modalOptions.Url).then(function(html) {
$elem = $compile(html)(scope);
element.append($elem);
});
}
}
}
The HTML is getting loaded correctly, but the selectize directive is not initializing .
I have also tired this inside the then method:
element.html(html)
$compile(element.contents())(scope);
That gave me the same result.
The issue I am having is I am receiving this message after the compilation of the HTML:
TypeError: element.selectize is not a function
Here is the plunk I am working with.
If you want angular.element to use jQuery you have to include jQuery in page before angular loads.
Demo works fine once you change script order
Updated demo
First solution
You have to include jQuery.js before Angular.js in index.html. This magic makes angular.element to use jQuery.
Solution 1
Second solution
You may replace element.selectize with $(element).selectize in angular-selectize.js on line 97. This makes angular-selectize script to use jQuery's selector instead of angular's.
Solution 2
Include jQuery in the page before Angular loads. Then angular.element will use jQuery.
Related
I am in the progress of changing an existing Chrome packaged app to use Angular. So far it works well, but I am not sure how to update the UI from outside Angular, for example in response to Chrome events.
As an example, I have a webview whose current address is monitored with a loadCommit. Here is just the simplified code:
HTML fragment:
<p>Current url = {{url}}</p>
Controller:
app.controller('MainController', function($scope) {
// This is the inital url
// It shows up in the HTML fragment
$scope.url = "http://stackoverflow.com";
});
Event listener:
webview.addEventListener('loadcommit', function() {
url = webview.src;
//How to update Angular framework with current value of url?
}
How do I get access to the controller's url variable so that the UI will reflect the changes? Simply referring to a global variable in the controller does not work, like:
$scope.url = url;
Use $apply.
From the Docs:
$apply([exp]);
$apply() is used to execute an expression in angular from outside of the angular framework. (For example from browser DOM events, setTimeout, XHR or third party libraries). Because we are calling into the angular framework we need to perform proper scope life cycle of exception handling, executing watches.
-- AngularJS $rootScope API Reference -- $apply
Update
AngularJS functionality should be added to webview tags by using an AngularJS directive.
HTML
<div ng-controller="MainController">
<webview current-src="url" id="foo"
src="http://stackoverflow.com/"
style="width:640px; height:480px">
</webview>
<p>Current url = {{url}}</p>
</div>
Directive
app.directive("webview",function() {
return {
restrict: "E",
link: function(scope,elem,attrs) {
var webview=elem[0];
elem.on("loadcommit", function(e) {
$scope.$apply(attrs.currentSrc +'='+ webview.src);
});
}
};
});
The example directive adds a loadcommit listener that sets the scope variable defined by the current-src attribute to the value of src property of the webview tag.
I have included the bootstrap ui module in my angular project and now I want to extend for example the datepicker controller 'UibDatepickerController' in the 'ui-bootstrap-tpls.js' with further functions.
Okay, I could edit the ui bootstrap file, but that is not that what I want.
I want a modularized file (maybe an own directive) so that there are no big problems when a ui bootstrap update is incoming.
Is that possible? What is best practice?
You can try injecting $controller and extending like this:
app.directive('myUiDirective', function ($controller) {
return {
link: function (scope, iElem, iAttr) {
angular.extend(this, $controller('UibDatepickerController', {$scope: scope}));
}
});
However I am not sure if you will be able to get controller from different module (in this case, from ui.bootstrap).
I am new to AngularJs and struck with an issue. I have "index.html" where I need to have the main section loaded via the <div data-ng-view=""></div>. Now, the data inside the view will be populated by the controller using the below code
.when('/',
{
controller:'controllers.IndexCtrl',
templateUrl:'/partials/index-partial.html'
})
Inside the index-partial.html file I have used the custom directive linke below:
<custom-carousel/>
The code for the carousel is below:
myApp.directive('customCarousel', function() {
return {
restrict: 'E',
replace:'true',
templateUrl: "/partials/carousel.html",
link: function(scope, element, attrs) {
$('.my-list').click(function(){
$('.my-list').removeClass('active');
$(this).addClass('active');
});
}
};
});
The issue with the above approach is that the jquery code inside the directive gets called twice and hence the toggling of the selected li does not work.
I have below questions:
Is the jquery function inside the directive called twice because its called from the partial and once again during the ng-view?
Whats the reccommended way of handling this scenarios?
Whats the best approach to fix this issue. If I remove the templateUrl from the controller and directly use the custom-carousel inside the html, this works perfectly but I want to load the directive using the ng-view and not directly in the index.html file.
Please let me know the best approach to solve this issue.
I have an AngularJS application, which hasn't been using the built in routing before now. I am refactoring the site, so it will be a SPA.
To do this I have change the app to use ng-view to switch between the different pages, instead of just having the server serve the different controllers
After this is done my endless scroll suddenly stopped working.
I have a directive which looks like this:
directiveModule.directive('whenScrolled', ['$window', function($window) {
return function(scope, element, attr) {
var raw = element[0];
angular.element($window).bind('scroll', function() {
console.log('test');
scope.$apply(attr.whenScrolled);
});
};
}]);
But now the scroll event is never fired.
If I take angular.element($window).bind('scroll', function() {..}); out and uses it in the controller instead it works fine, but it just seems like a hack.
Is there any way to bind to the page scroll event inside a directive, which is inside a controller, which is inside a ng-view?
Are you sure the element with the directive which is inside the controller and then the ng-view is added to the DOM?
More code (A Fiddle) would help.
I m trying to use Kendo grid in my angular js app. I m creating a directive so I can use it in different tables among the application. Once the ng-repeat renders the dom I want to call:
element.kendogrid().
Since there is no post-render callback for ng-repeat, some people suggest using two directives:
1-
angular.module('app')
.directive('rowDirective', function () {
return function(scope, element){
if (scope.$last){
scope.$emit('LastElementMessage');
}
};
});
2-
angular.module('app')
.directive('tableDirective', function () {
return function(scope, element){
scope.$on('LastElementMessage', function(event){
$(element).kendoGrid({
scrollable: true,
sortable: true,
});
});
}
});
This approach works fine and everything is executed in the order it should. The ng-repeat works fine by it self, which means it renders the items in the right order but when I use the kendo-grid, it renders this: {{customer.CustomerID}} inside the grid. Has anyone gone through something like this ?
Well, perhaps you should take a look at Angular Kendo UI project at http://kendo-labs.github.io/angular-kendo/ - it does rather good job of "marrying" Kendo UI with AngularJS.
See http://demos.telerik.com/kendo-ui/grid/angular.
There are specific custom directives that enable kendo ui to play nicely with angular js. E.G. k-data-source, k-columns, k-selectable, k-pageable. These should be included in the latest version of kendo ui. Just make sure to include "kendo.directives" as a dependency on your top level-module :
var MyModule = angular.module('MyModule', ["ngRoute", "kendo.directives"]);