I'm trying to switch a 1.5x project over to components and use the new component-router. I'm having an issue with how to programmatically access the $router in a couple of components that aren't sitting inside of a directive. Basically I have header and sidebar components which need to be able to do $router.navigvate, but using bindings: {$router: "<"} gives me an undefined $router.
I think I might just need to restructure the app a little bit, but I'm not sure how to go about it.
Currently in my Index.html I have ng-app defined on the body, and then the main app module inside of that (<app></app>).
My main app component has a template with basically my "masterpage".
So app.html has a <header> component, <sidebar> component, and then <ng-outlet> for the main content. With UI-Router I just used the $state service in the header/sidebar controllers to find the active state or navigate to a new state.
With component-router I can't figure out how to get the $router into the header/sidebar controllers.
Any ideas?
use $rootRouter in the controller
function controller($rootRouter){
$rootRouter.navigate(["someComponent"])
or $rootRouter.navigateByUrl("/url")
}
Related
Started learning AngularJS today, using webpack and ES6. I'm kind of stuck on a simple problem that I cannot figure out. I'm building a really simple SPA app, like a shopping cart app, which should have the "header" component with a couple of links to other pages and the sum and total of shopping cart.
One of these other controllers could be just a random dummy page, one could be the shopping cart summary, and the main controller would be where the user can actually add items to the shopping cart.
What I have thus far is just the following routes:
export default function routes($stateProvider) {
$stateProvider
.state('main', {
url: '/',
template: require('./main.html'),
controller: 'MainController',
controllerAs: 'main'
})
.state('other', {
url:'/other',
template: require('./other.html'),
controller: 'OtherController',
controllerAs: 'other',
})
}
index.js:
export default angular.module('app.main', [uirouter, productService])
.config(routing)
.controller('MainController', MainController)
.controller('OtherController', OtherController)
.name;
productService isn't relevant here, so I exclude that code.
Just as a test I tried to set the OtherController as a separate view in index.html:
<body>
<div ui-view="other"></div>
<div class="container" ui-view></div>
</body>
Kind of like suggested here: How to update partial of html using ES6 syntax with angular-webpack-seed
Also tried to use ng-controller="other" instead of ui-view="other", but that throws error:
The controller with the name 'other' is not registered
And I don't know where I would then register it...
Some places I read that you could use a directive for making a "header"/navbar, but that doesn't seem correct to me at all. Also tried that though, in this way: https://stackoverflow.com/a/33714913/6294072 Read about ng-include, but that wouldn't work, since I need the service for the shopping cart.
I am missing something fundamental here, but can't figure it out. My brain is also (unfortunately) wired on Angular (4), since I have some experience with that :)
Sorry for the noob question, I feel ashamed, but I have been struggling for this for hours now and therefore going crazy. Help is very much appreciated!
Use components instead of controllers with controllerAs. You'll find it much more similar to Angular 4. Then depending on how you want to do it, you can use either bindings or requires to create relationships between your components.
Since you have tight control over this, I would go with requires. Create a component with your navbar and stuff in it, then create child components and require the parent in them. We have a generic in-house framework for this stuff. The outer component we call the site, so we get a reference to it in our child components like this:
require: { site: '^f1Site' }
If you're not already doing so, use ui-router 1.0.x and use route to component to handle navigation & state.
Index.html just has <f1-site>Loading</f1-site> in it's body.
The f1-site template has basic layout stuff in it - including navbars and such that we've moved off into their own components - and then the ui-view directive is on the tag where we want to load all of dynamic components.
I am working on custom directives in AngularJS and getting help from Mark Zamoyta's tutorials from PluralSight.
M using UIRouter in angular which is not working well in custom direcives while ngRoute is working well.Here is position of ui-view
<ng-transclude></ng-transclude>
<div ui-view></div>
In Controller i've this code to use routes/states getting from custom directive.
$scope.$on('ps-menu-item-selected-event', function (evt, data) {
$scope.routeString = data.route;
//$location.path(data.route);
$state.go(data.route);
checkWidth();
broadcastMenuState();
});
Now,I f i use ngroute then it is showing partial/template at right place but if i use ui router it goes out of ui-view ang show partials/templaes but not in between
<div ui-view></div>
i have thse searches who lead me to downgrading ui router's version but no success.
1.ui-view doesn't work when used inside angularjs custom directives
2.https://github.com/angular-ui/ui-router/issues/774
Any Help?????
When you use $location.path(url), you pass in something like /home/item into the url, but when you use $state.go(state), you pass in the state name like home.item. Make sure you pass the right thing.
I'm using UI-Router to mange my routing on my application.
One item I've hit a snag on it with my menu which is the main view that the controllers will use.
for example I have a home link that should be
index.htm#/home/3
index.htm#/settings/3
3 is the companyId
but it seems that I can't access it that way. Does anyone have a suggestion as to how I could make that work?
Parent states should not be accessing the parameters of child states, but there is a little bit of magic that ui-router provides that might help. This is ui-sref-active. This directive will add css classes to html elements that have a ui-sref directive and that state is currently active. I think this would be sufficient to solve the problem that you have.
I'm currently using jQuery to display modal windows, the function basically builds some HTML and then does $('#myElement').append(modalHtml);
Inside that modal HTML I have <div ng-controller="MyController">...</div> however when the modal is displayed the controller doesn't seem to get initialized. Is this because it's being added to the DOM outside of angular's scope? If so is there anyway when I run that code I could notify angular to look out for changes?
The breakdown of how it is at the moment is Angular runs loadModal() through an ng-click on an element. loadModal() calls modal(), and modal() builds the html and adds it to the DOM. Modal is in a script of just standalone helper functions.
The modal controller won't be called because you're not parsing or compiling the appended DOM code with Angular. Hence, Angular will not 'notice' this change and as a result it will not run any controllers or directives in the added DOM. The best way to solve this kind of problems is by adding a custom directive.
As you're trying to make a modal work, you could also take a look at existing modal adaptations for Angular, such as the one in AngularUI.
Can I implement something like:
$scope.showDashboard = function () {
$scope.dashboardPath = "/Widgets/Weather/View.htm";
$scope.widgetController = 30;
require(['/Widgets/Weather/Controller.js'], function (w) {
whatShouldIputHere = w;
});
};
<div ng-include src="dashboardPath" ng-controller="whatShouldIputHere?"></div>
Is it possible to assign a controller to ng-include dynamically?
There could be many widgets on the dashboard
There is a project in development that implements dashboard functionality with AngularJS.
Features:
Adding/removing widgets
Widgets drag and drop
Any directive can be a widget
Running Demo http://nickholub.github.io/angular-dashboard-app
Demo source code https://github.com/nickholub/angular-dashboard-app
Dashboard directive itself https://github.com/nickholub/angular-ui-dashboard
We created an angularjs based dashboard in the open source hawtio project. You can noodle the code here if you like:
https://github.com/hawtio/hawtio/tree/master/hawtio-web/src/main/webapp/app/dashboard
For each widget on the dashboard we compile the partial directly with a child scope
https://github.com/hawtio/hawtio/blob/master/hawtio-web/src/main/webapp/app/dashboard/js/dashboard.ts#L142
Though we had to patch angularjs to allow us to use custom injection on child scopes. e.g. so that we can use a different implementation of $location for each child widget (so it thinks its on its own real URL etc). Hopefully when custom injectors are supported we can move to that.
Instead of using dynamic controllers why not use a single controller(the one which has the showDashboard method). Adding dynamic controller with ng-include will result in nested controllers which is illegal i guess. And instead of using ng-include as an attribute use it as an element.
<ng-include src="dashboardPath"></ng-include>