Could you please tell me why alerts display two times on button click?
here is my plunker
http://plnkr.co/edit/vtmYAG2d1gmnPjnxovJw?p=preview
/*global define, console */
define(['app'], function(app){
'use strict';
app.controller('LoginCtrl', ['$scope', function($scope) {
$scope.login = function () {
alert("Login is clicked")
};
}]);
});
If you use a newer version of Ionic it works:
http://plnkr.co/edit/K2BLrUyOEeoDxHc9LyTl?p=preview
I used http://code.ionicframework.com/1.0.0/js/ionic.bundle.min.js
your example uses
http://code.ionicframework.com/1.0.0-beta.1/js/ionic.bundle.min.js
requirejs.config({
paths: {
ionic:'http://code.ionicframework.com/1.0.0/js/ionic.bundle.min',
},
shim: {
ionic : {exports : 'ionic'}
}, priority: [
'ionic'
],
deps: [
'bootstrap'
]
});
The digest cycle runs at least two times by angularjs. So, probably the reason for the alert is appearing two times is digest cycle.
But others said to change version and you would get alert calling only once. But if you don't want to change the version, there's a workaround to this:
$scope.login = function () {
alert("Login is clicked");
$scope.login = function(){
return false;
}
};
working demo
This method allows you to call function only once. It might be helpful for others who want to stop digest cycle.
Problem fixed you have used obsolete minified version of ionic and requirejs non-minified.
Just change your ionic version to --
http://code.ionicframework.com/1.0.0/js/ionic.bundle.js
and requireJs to
RequireJS 2.1.17
it's working fine ...change version in your fiddle
Related
I recently converted my project from bootstrapping angular through the ng-app default method to using RequireJs and doing so manually. Everything works fine most of the time, but some percentage of the time I get errors saying my controllers and services of the login page are undefined, so the controller doesn't properly load and values aren't bound.
I believe the problem stems from the order of execution of dependencies. First, here are the errors:
Error: [ng:areq] http://errors.angularjs.org/1.3.15/ng/areq?p0=NavController&p1=not%20aNaNunction%2C%20got%20undefined
Error: [$injector:unpr] http://errors.angularjs.org/1.3.15/$injector/unpr?p0=UsersServiceProvider%20%3C-%20UsersService%20%3C-%20LoginController
So far I am only seeing this problem in Chrome, and when I have the javascript console open everything seems to work. I have inserted a few console.log() statements to get some visibility into the order of activity within these scripts. For three files, routeConfig.js, nav.js and usersService.js I have a console.log on the first line within the define function and another one on the first line of the angular definition function:
routeConfig.js:
define(['angularAMD',
'angular-route',
'uiBootstrap',
'lib/angularSlideables',
'lib/ng-infinite-scroll',
'lib/angular-modal-service'], function (angularAMD) {
console.log('top of routeConfig');
var app = angular.module('svlPlatform', ['ngRoute', 'ui.bootstrap', 'angularSlideables', 'infinite-scroll', 'angularModalService']).value('THROTTLE_MILLISECONDS', 750);
app.config(['$routeProvider', function ($routeProvider, $httpProvider) {
console.log('inside routeConfig');
// Because angularAMD is built on requireJS, the following paths to controllerUrl follow requireJs's conventions.
// They don't need a .js extention and they are relative to the baseUrl specified in require.config.
$routeProvider
.when('/login', angularAMD.route({
templateUrl: 'views/login.html',
controllerUrl: 'controllers/login'
}))
.when('/me', angularAMD.route({
templateUrl: 'views/me.html',
controllerUrl: 'controllers/me'
})) //this continues and returns app...
nav.js:
define(['config/routeConfig', 'services/authService', 'services/usersService', 'services/menuService'], function(app) {
console.log('top of nav controller');
app.controller('NavController', ['$log', '$anchorScroll', '$location', '$rootScope', 'AuthService', 'UsersService', 'MenuService',
function ($log, $anchorScroll, $location, $rootScope, auth, users, menu) {
console.log('inside nav controller');
var vm = this;
menuScope = this;
function loadMenu() {
menu.items().then(function(response){
vm.menuItems = response.data.menuItems;
$('body').css("background-color","#f2f2f2");
markMenuActive(vm.menuItems);
}, function(error) {
console.log('There was a problem getting the menu data.');
});
} //continues...
usersService.js
define(['config/routeConfig', 'utils/urlBuilder', 'services/menuService'], function (app, _urlBuilder) {
console.log('top of users service');
var urlBuilder = _urlBuilder;
app.factory('UsersService', ['$http', 'MenuService', function ($http, menu) {
console.log('inside users service');
var meCache;
var refreshMeCache = function () {
meCache = $http.get('/api/v1/users/me');
menu.refreshItemsCache();
}; //continues...
Here is my requireJs config:
require.config({
baseUrl: 'javascripts',
paths: {
'angular': '//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min',
'angular-route': '//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-route.min',
'bootstrapJs': '//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min',
'uiBootstrap': '//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.1/ui-bootstrap-tpls.min',
'angularAMD': '//cdn.jsdelivr.net/angular.amd/0.2.0/angularAMD.min'
},
shim: {
'angularAMD': ['angular'],
'bootstrapJs': [],
'uiBootstrap': ['angular'],
'lib/angularSlideables': ['angular'],
'lib/ng-infinite-scroll': ['angular'],
'angular-route': ['angular'],
'lib/angular-modal-service': ['angular']
},
deps: [
'bootstrapJs',
'config/routeConfig',
'services/authService',
'services/usersService',
'services/menuService',
'controllers/nav',
'controllers/main',
'lib/angular-modal-service',
'config/config',
'app'
]
});
When the login page (the first page the app loads) is loaded correctly, i see this after I open the console:
top of routeConfig
top of users service
top of nav controller
inside routeConfig
inside users service
inside nav controller
but when the page doesn't load properly, this is what i'm seeing in the console.
top of routeConfig
inside routeConfig
top of users service
top of nav controller
...then errors
I don't understand the bootstrapping process or requireJs' load process enough to figure out why this is happening and how to fix it. Thank you to anyone who has any ideas. Thanks.
Perhaps this is the best way to solve this problem, perhaps it is not. I gave up trying to use require to specify any kind of load order in the require config or using any of the module definitions. I forced it by having several of my controller and service modules return the app, and have them dependent in series rather than in parallel, this forces require to run the scripts in the order I specify.
So, rather than have nav.js and usersService.js dependent on routeConfig.js, which provides the app object for both of those components, I have the service dependent on routeConfig.js, and the nav.js module dependent on the usersService (which now returns its app object). This method could continue to include other controllers and services which need to be loaded before bootstrapping. I then finally call another file, app.js, which calls the angular.bootstrap() (angularAMD.bootstrap() in my case), and everything works now.
I am using for my Slide up/down effect this genius written .js modul.
https://github.com/EricWVGG/AngularSlideables
http://jsfiddle.net/3sVz8/19/
I could include it to my project and it is working the way I want.
But now I want to trigger this inside my controller, how do I do this?
html
Open smoothly
<div id="derp" class="slideable">
open/hidden content
</div>
.js
var myApp = angular.module('myApp', ['ngAnimate', 'angularSlideables']);
angular.module('angularSlideables', [])
.directive('slideable', function () {
return {
all the code from the github
})
myApp.controller("ContactControllerHeading", function ($scope, $http) {
$scope.Triggerhere= function() {
/* trigger here this slide-toggle="#derp" */
}
});
Thank you a lot
I gave up solving it with this. I used jquery slide up and down function which seems to be a adequate solution
http://www.w3schools.com/jquery/eff_slidetoggle.asp
I am using AngularJS and have implemented routing using it. I want to make sure whenever route changes template is fetched from server and not obtained from cache, is there a way I can force this to happen ?
This should hopefully work:
app.run(function($rootScope, $templateCache) {
$rootScope.$on('$viewContentLoaded', function() {
$templateCache.removeAll();
});
});
According to the comment on the accepted answer, this should be the correct code:
app.run(function($rootScope, $templateCache) {
$rootScope.$on('$viewContentLoaded', function() {
if($templateCache) {
$templateCache.removeAll();
}
});
});
I'm trying for the first time to use AngularJS in conjunction with RequireJS using this guide as a basis. As far I can tell after a lot of debugging I'm loading all my modules in the correct order, but when the application runs Angular throws an Error / Exception with the following message:
Argument 'fn' is not a function, got string from myApp
I've seen this message before due to syntax errors, so even though I've looked trough the code multiple times I won't rule out the possibility of a simple syntax error. Not making a Fiddle just yet in case it is something as simple as a syntax error, but I'll of course do so if requested.
Update: I just noticed when setting ng-app="myApp" in the <html> tag I also get an additional error,
No module: myApp
Update II: Okay, it turns out it indeed was an syntax error in the only file not included below. I am though still left with the problem from update I.
RequireJS bootstrap
'use strict';
define([
'require',
'angular',
'app/myApp/app',
'app/myApp/routes'
], function(require, ng) {
require(['domReady'], function(domReady) {
ng.bootstrap(domReady, ['myApp']);
});
});
app.js
'use strict';
define([
'angular',
'./controllers/index'
], function(ng) {
return ng.module('myApp', [
'myApp.controllers'
]);
}
);
controllers/index
'use strict';
define([
'./front-page-ctrl'
], function() {
});
controllers/module
'use strict';
define(['angular'], function (ng) {
return ng.module('myApp.controllers', []);
});
controllers/front-page-ctrl
'use strict';
define(['./module'], function(controllers) {
controllers.
controller('FrontPageCtrl', ['$scope',
function($scope) {
console.log('I\'m alive!');
}
]);
});
Delete ng-app="myApp" from your html.
Because it has bootstrapped manually
ng.bootstrap(domReady, ['myApp']);
RequireJS docs on Dom ready state:
Since DOM ready is a common application need, ideally the nested
functions in the API above could be avoided. The domReady module also
implements the Loader Plugin API, so you can use the loader plugin
syntax (notice the ! in the domReady dependency) to force the
require() callback function to wait for the DOM to be ready before
executing. domReady will return the current document when used as a
loader plugin:
So, when you require 'domReady' the result is a function:
function domReady(callback) {
if (isPageLoaded) {
callback(doc);
} else {
readyCalls.push(callback);
}
return domReady;
}
But when you append the domReady string with ! sign the result will be the actual document element:
'use strict';
define([
'require',
'angular',
'app/myApp/app',
'app/myApp/routes'
], function(require, ng) {
require(['domReady!'], function(domReady) {
// domReady is now a document element
ng.bootstrap(domReady, ['myApp']);
});
});
I'm in the beginning stages of building a large app with AngularJS and RequireJS. Everything loads find but directives aren't manipulating the DOM as they should. No errors are being reported and rest of the app works fine: Views are loaded and $scope is bindable. Examining the console shows that all the files loaded. I'm assuming this is a lazy load issue in that my directive is simply not loading at the correct time. I'd appreciate any insight into how to properly load directives in this regard. Unless it's a part of Angular's jqLite, please refrain from suggesting jQuery.
config.js
require.config({
paths: { angular: '../vendor/angular' }
shim: { angular: { exports: 'angular' } }
});
require(['angular'], function(angular) {
angular.bootstrap(document, ['myApp']);
});
myApp.js
define(['angular', 'angular-resource'], function (angular) {
return angular.module('myApp', ['ngResource']);
});
routing.js
define(['myApp', 'controllers/mainCtrl'], function (myApp) {
return myApp.config(['$routeProvider', function($routeProvider) {
...
}]);
});
mainCtrl.js
define(['myApp', 'directives/myDirective'], function (myApp) {
return myApp.controller('mainCtrl', ['$scope', function ($scope) {
...
}]);
});
myDirective.js
require(['myApp'], function (myApp) {
myApp.directive('superman', [function() {
return {
restrict: 'C',
template: '<div>Here I am to save the day</div>'
}
}])
});
home.html
<div class="superman">This should be replaced</div>
home.html is a partial that's loaded into ng-view
Angular cannot load directives after it has been bootstrapped. My suggestion is:
Make myDirective.js do a define(), not a require()
Make sure myDirective.js is run before the require(['angular'],...) statement in config.js, e.g. do require(['angular','myDirective'],...). For this to work, myDirective should be shimmed to depend on angular - thanks # David Grinberg.
As a sidenote, take a look at this in Stackoverflow/this in GitHub, we have been trying to do RequireJS + Angular play together.