I'm usnig AngularJs 1.2.25. I have a route config:
$routeProvider.when(
'/config-root',
{
templateUrl: configRootTemplate,
controller: "ClientConfig",
}
).when(
'/config-action/:action/:_id',
{
templateUrl: configActionTemplate,
controller: "ClientConfigAction",
}
).otherwise({redirectTo: '/'});
In the ClientCOnfig controller, I have a $scope.listConfig variable binding with template for creating, updating list of config.
Everything ok when the first time I visit "config-root" route, I can generate, update... the list.
But when the second time or so far, $scope.listConfig change properly when generate list, update... but the template does not change.
I think when I visit that route again, a new instance of $scope created and does not binding with the template.
How can I fix it?
You can use rootScope to preserve the value for the next time.
change that $scope to $rootScope and access that when ever its required.
If you don't want to pollute the $rootScope you can just store the values in a localStorage as a string and fetch it when ever its required.
// To store the value
localStorage['config'] = JSON.stringify(someObj)
// To fetch the value
var myConfigObj = JSON.parse(localStorage['config'])
Related
this is my first question in stackoverflow!
I have troubles with angular-meteor helpers, i can't get them to work.
I defined this helper block inside my controller.
this.helpers({
testers: () => { return Testers.find() }
});
I created the "Testers" collection.
Testers = new Mongo.Collection("testers");
Also made the publication and subscription with:
$reactive(this).attach($scope);
this.subscribe('testers');
Inside the browser's console i already have access to "Testers" collection and it is reactively updating with Mongo database, i checked that already.
For testing purposes i placed inside the "testers" helper function a console.log and it is indeed getting executed but i dont know why it is not creating the "$scope.testers" variable.
I am using ui-router so i assigned the controller with:
.state('user.index', {
url: '/',
templateUrl: 'client/user/cheques/list.html',
controller: 'testCtrl',
})
I placed a regular variable inside the scope and it gets to the view without trouble as always but i can't get the helper variables.
Does my controller in router assignation matter? Im missing something?
using: angular 1.3.7, angular-meteor 1.3.6
It will create this.testers. you should use controllerAs in your router ,and then use vm.testers (or your other controller as name)
I am new to Angular so bear with me.
I have a controller that handles the search functionality within a page.
As a user changes the search the url changes to reflect the user interaction. Then there are $http.post calls to an API to retrieve those values within the URL. A repeater in a separate controller is updated appropriately.
This works great and the scope changes correctly.
But how do I handle initial load?
If a user clicks a saved search.
Example:
http://blah/blah/blah/Search/Status-1%7CBeds-3
I would want the search fields and the scope to be set appropriately but then the same functionality should continue.
What is the best way of doing this?
If code is needed then ask, but this is more of a which direction to go question then a fix my code question.
You probably want AngularJS routing and the $routeParams object.
If that is not adequate, you can use the $location service to extract information from the URL and write it to the $scope in your controller constructor function.
If you use ui-router you can define the search string as a parameter that can be used when deep linking
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url:'/home',
templateUrl: 'templates/home.html',
controller: 'HomeController'
})
.state('search', {
url: '/search/:searchtoken',
templateUrl: 'templates/search.html',
controller: 'SearchController'
});
http://www.funnyant.com/angularjs-ui-router/
One solution is to populate the search variable with the url params. Something like:
if params
$scope.searchInputVal = params
$scope.doPostRequest()
(sorry for the coffee script syntax)
and just ensure whatever function you have to update these search parameters is firing onChange() or onClick() whichever you're using to fire the post request to begin with.
In AngularJS, is there a way to intercept a route change that is not defined in the routeProvider so the route can be looked up in the database and, if a valid match in the database, the new route can be added to the routeProvider?
I've read it is possible to add, dynamically, a route, but I need to do it when the current route has no match.
I would have used the otherwise method of $routeProvider to load a predefined page (controller) to handle undefined routes.
otherwise({
templateUrl: 'addRoute.html',
});
And then, into this controller, get the current route requested using $location ($location.url()).
Add this route dynamically if needed :
$route.routes['/new'] = {templateUrl: 'new.html'};
Finally, redirect to this route using :
$location.path('/new');
Obviously, for this to work you will need to inject $route and $location as dependency to your controller.
Assuming you can do it in controller, you can capture this event as following:
$rootScope.$on("$routeChangeSuccess", function (event, next, current) {
if(!angular.isDefined($route.current.$$route))
addDynamicRoute('using techniques mentioned above');
else
handleOtherStuff();
});
I'm trying to get my view template updated every 10 minutes. Using this setup in the state config doesn't work:
.state('home', {
url: '/',
controller: 'landing',
templateProvider: function($templateFactory, $interval) {
var templateId = 0;
return $interval(function(){
var template = templateId % 2 == 0 ?
'landing-primary.html':'landing-secondary.html';
templateId++;
return $templateFactory.fromUrl('views/templates/' + template);
}, 600000);
}
})
What's the best way to achieve such work?
The templateProvider option should be a function that returns an html string or a promise that resolves with an html string. It's mainly present so that you can generate html that somehow makes use of $stateParams.
What you're trying to do wouldn't normally be done through route/state definitions; what you've described is logic that should be in a directive or controller. While it's hard to say for sure without more information about exactly what you're trying to achieve, it sounds like what you really need is a single "landing" page with the content of both templates divided by an ng-switch directive that gets bound to a model property. Then in your controller you would set an $interval to change that model property every 10 minutes.
Alternatively, maybe what you want is two states, in which case the pair of states would each have in their corresponding controllers a $timeout that toggles to the other state.
I'm trying to integrate Rails with Angular to turn part of my app into a one-page-app using Angular. I have a main module with the following (coffeescript) code for routing:
MainApp.config ($routeProvider) ->
$routeProvider
.when '/',
{
templateUrl: 'post_archive.html'
}
.when '/new',
{
templateUrl: 'new_post.html'
}
.when '/:postSlug',
{
templateUrl: 'show_post.html'
}
.when '/:postSlug/edit',
{
templateUrl: 'edit_post.html'
}
.otherwise
redirectTo: '/'
The main view for this section of the site starts with this haml
%div{ ng_controller: 'PostCtrl', ng_init: 'init()', ng_cloak: true }
And the PostCtrl has this init function:
$s.init = ->
$s.getPost().then ->
$s.getPostList() unless $s.postList
$s.getPreviousPost()
$s.getNextPost()
The idea is, the current post, as well as the next and previous, need to be recalculated, but the postList should remain the same, so it doesn't need to be re-fetched on every page load.
However, it is. It seems that the scope is getting dumped on every page load, which means that it's not really behaving at all like a one-page app, and there's a flicker while the postList reloads, whenever a link is followed within the app.
The links' rendered HTML looks like this, for example:
<a id="link_name" ng_href="#/post-name" class="ng-binding" href="#/post-name">
Post Name
</a>
Any idea what I'm doing wrong here? (Does this have to do with all the pound signs that angular seems to be inserting before the final URL slash?)
This is the expected behavior. If scope.init() is being called on init, it should be called on page load, as the scope will be bound (and initialized) each time its controller route will be accessed.
To avoid that behavior, simply call init() on demand, or — better yet — escalate postList to a higher level in the scope hierarchy (above ng-view, where the route change takes place and re-binds scopes to views), e.g. in the $rootScope. That way its initialization / evaluation won't be tied to the $s scope's init.
To illustrate this [1]:
You can define postList in the topmost scope, — it will be prototypically (is that even a word?) inherited:
$rootScope.postList = [];
It's also sufficient to save it in a parent controller — so long as it's higher in the hierarchy than the router's scope (where ng-view resides), as same rules apply for inheritance with controller's scopes. Something along these lines [2]:
// in the view
%div { ng_contoller: 'ParentCtrl' }
%div { ng_view }
%div{ ng_controller: 'PostCtrl', ng_init: 'init()', ng_cloak: true }
// in ParentCtrl
$s.postList = [];
[1] Caution! not tested!
[2] Risk of bogus code — I don't really know HAML!