Map two controller to one view with ngRoute in Angular? - angularjs

Hi everybody I am new to angular and still trying to get the basics down. I have a view that has two controllers controlling two different pieces of that view:
<div class="row" ng-app="appDiary">
<div ng-controller="entryController as vm">
....
</div>
<div ng-controller="otherController as vm">
....
</div>
<div>
entryController.js / otherController.js:
angular.module("appDiary").controller("entryController", entryController);
function entryController($scope, $http, $filter, service) {
...functionality here...
}
Basically the view html has gotten long and I want to break it up into templates. I tried searching around and using the ngRoute.
angular.module('appDiary', ['simpleControls', 'chart.js', 'ngRoute']);
.config(function ($routeProvider) {
$routeProvider.when("/", {
controller: "entryController", "otherController" // Want both controllers here
controllerAs: vm,
templateUrl: "/views/entry.html", "/views/other.html"
});
});
How do I get Angular to map two controllers/templates to one route? Is there a better way to do this? I tried using some suggestions from Routing in angularjs for mutliple controllers? and couldn't get anything working. Thank you!

Related

Combining functions from two separate controllers into one ng-click

I am new to angularJS and nodeJS and am working on a project. As it stands there exists two different controllers let's say "controllerA" and "controllerB" that have "functionA" and "functionB" being triggered by ng-click events on "buttonA" and "buttonB".
If I want to trigger functionA and functionB from one "buttonC", how would I do that?
Thanks!
Just call controllers on two different divs
<div ng-controller="controllerA">
<div ng-controller = "controllerB">
<input ng-click="functionA();functionB();"/>
</div>
</div>
OR
call one controller controllerA in your routes for your view.
and call another controller controllerB in your view.
.state('app.example', {
url: '/example',
controller: 'controllerA',
templateUrl: 'example.html',
})
<div ng-controller="controllerB">
<input ng-click="functionA();functionB();"/>
</div>
By this, you can access two controllers

Use ui-view as the template for state inside ui-router instead of an external template

I have an app that is currently using the angular ui-router module dependency. The only aspect of the ui-router that I'm currently employing is the ability to apply/modify $stateParams to $scope and vice versa so the URL can change the way data is displayed in the controller to a user on arrival (i.e. url?param=something will filter the data by something).
I have the following in my app.config to set the state:
$stateProvider
.state('root', {
url: '/?param',
templateUrl: 'template.html',
controller: 'listController',
params: {
param: {
value: 'something',
squash: true
}
}
});
On my homepage, template.html successfully loads when the app is instantiated as such:
<div ng-app="myApp">
<div ui-view>
</div>
</div>
However, I have reached a roadblock and realize that calling the template from within templateUrl isn't going to work, as this app is being built inside another framework and therefore needs to be called from within the homepage itself to access its full capabilities.
Being a noob at AngualrJS, I was wondering if anyone can tell me what the best way is to accomplish this while still keeping the logic of $stateParams and other ui-router capabilities intact for the future.
For instance, could I just remove the templateUrl parameter from my state and call the controller directly inside the ui-view like this:
<div ng-app="myApp">
<div ui-view>
<div ng-controller="listController">
do something
</div>
</div>
</div>
I also looked into changing the entire logic from using ui-router to simply using the $location service but I'm wondering if there is a way to accomplish this without needing to over-do everything.

AngularJs :: Share data between Views and parameters

I'm creating an App with Ionic Framwork.
The Front is ok, and I made the view transitions using $stateProvider.
But I need to do the APP features and other functionalities. I have 2 major problems
1) Pass parameters through href=""
2) Execute some functions after the view transition e when the data is processed show the info on the new View.
Couldn't go further because I'm newbie at Angular and the other examples I searched were not specific.
That's what I got so far::
INDEX.HTML
<body ng-controller="AppController as controller">
<ion-view title="View1"><ion-content>
<a href="#/view2" ng-click="controller.test1">
<button class="button-style">TEST 1</button>
</a>
<a href="#/view2" ng-click="controller.test2">
<button class="button-style">TEST 2</button>
</a>
</ion-content></ion-view>
...
View2.HTML
<ion-view title="View2"><ion-content>
<input type="text" value="{{controller.parameter}}" />
</ion-content></ion-view>
APP.JS
app.config( function($stateProvider, $urlRouterProvider){
$stateProvider
.state('view2',{
url:'/view2',
templateUrl:'views/view2.html'
})
...
app.controller('AppController', ['$scope', function($scope){
parameter = '';
this.test1 = function(){
alert('test1');
parameter = 'One';
};
this.test2 = function(){
alert('test2');
parameter = 'Two';
};
}]);
I've tried alot. But now it's just guessing :(
I didn't understand how Controllers and $scope works. I've saw some examples using factory and service, even the CodeSchool (awesome by the way) coudn't help me...
So, any good soul can bring some light here?
Sorry about my misspelled english
First of all, you should be using the ui-sref attribute in your <a> tags (since you're using states, although using href works too), like this:
<a ui-sref="view2"></a>
And if you want to pass parameters, you have to configure your state's url to accept parameters:
url: '/view2/:parameter'
To access parameter in your controller, you'll also need to inject $stateParams into your controller:
app.controller('AppController', function($scope, $stateParams) {
});
And you access parameter via $stateParams.parameter like this:
app.controller('AppController', function($scope, $stateParams) {
alert($stateParams.parameter);
$scope.parameter = $stateParams.parameter;
});

How to prevent losing data when moving from one state to another in multi-step form?

I am new to web programming and especially to AngularJS.
So maybe my question will seem naive to some of you.
I'm developing a single page application using angular-ui-router.
I have created a multi-step form that contains 3 states:
(function () {
"use strict";
angular.module("sensorManagement", ["ui.router", "ngAnimate", "ngResource", "toaster"])
.config(["$stateProvider", "$urlRouterProvider", function ($stateProvider, $urlRouterPorvider) {
$urlRouterPorvider.otherwise("/Sensor/Home");
$stateProvider
.state("MultiStepForm", {
url: "/Sensor/MuiltyStepForm",
templateUrl: "/app/MultiStepForm/MuiltyStepForm.html",
})
.state('MultiStepForm.step1', {
url: '/step1',
templateUrl: '/app/MultiStepForm/FormStep1.html'
})
.state('MultiStepForm.step2', {
url: '/step2',
templateUrl: '/app/MultiStepForm/FormStep2.html'
})
.state('MultiStepForm.step3', {
url: '/step3',
templateUrl: '/app/MultiStepForm/FormStep3.html'
});
}]);
})();
Here is the HTML code:
<!-- form.html -->
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div id="form-multiple-step">
<div class="page-header text-center">
<!-- the links to our nested states using relative paths -->
<!-- add the active class if the state matches our ui-sref -->
<div id="status-buttons" class="text-center">
<a ui-sref-active="active" ui-sref=".step1"><span>STEP1</span></a>
<a ui-sref-active="active" ui-sref=".step2"><span>STEP2</span></a>
<a ui-sref-active="active" ui-sref=".step3"><span>STEP3</span></a>
</div>
</div>
<form id="single-form">
<!-- our nested state views will be injected here -->
<div id="form-views" ui-view></div>
</form>
</div>
</div>
</div>
As you can see I have 3 states and each state has it's own view. The views have multiple elements (textboxes and checkboxes).
When the user enters some data for the STEP1 view and moves to the next step (STEP2 or STEP3) then at some point goes back to STEP1 all data is deleted. I checked with fiddler and can see that when I move from one state to another a call is made to the server and a new view generated.
My question is how can I prevent the lose of data when I move from one state to another? Do I have to use caching? Or maybe there is another way to prevent server calls and keep the data alive until the submit button clicked.
When you feel you have to save data across your controllers in your app. you should use a service.
app.factory('sharedDataService', function ($rootScope) {
console.log('sharedDataService service loaded.');
// do something here that can be shared in other controller
});
//pass this service in your controller to use it there
app.controller('Controller2', ['$scope', 'sharedDataService', function ($scope, sharedData) {
console.log('Controller2 controller loaded.');
//get data from shared service
}]);
find a useful Fiddle here
Cheers if it helps!
I think what you need to do is share you $scope between the parent and child stats. here is the stackoverflow post with good example. https://stackoverflow.com/a/27699798/284225

Changing attributes of enclosing containers based on current view

This is rather a conceptual than a strictly technical question.
I have the following index.html:
<div class="container"><div ng-view=""></div></div>
In my app.js, I have the following route configuration:
$routeProvider
.when('/questions', {
templateUrl: 'views/questions.html',
controller: 'QuestionsCtrl'
})
.when('/result', {
templateUrl: 'views/result.html',
controller: 'ResultCtrl'
})
.otherwise({
redirectTo: '/questions'
});
Which means that, based on the URL, different views are loaded in <div ng-view="">. Now, in order to have those views correctly rendered, I need to set style attributes on the enclosing <div class="container"> (I use Leaflet.js in one of those views and thus I need to temporarily set the width and height of the container to 100%, for a full screen map).
How would I do this best, i.e. "The Angular Way"? I looked at the $viewContentLoaded event of the ngView directive, but it doesn't seem to be the right thing as it seems to be only fired when the respective view is completely loaded and not at the initialization of the view (and thus the map, which needs a correctly styled container from beginning on). Should I use a controller that is defined on the body tag, for example? Or a service? I am completely clueless and want to make it right.
Use a controller that listens to $routeChangeSuccess on the $rootScope.
<body ng-app="X" ng-controller="app">
<div class="container" ng-class="containerClass">
<div ng-view=""></div>
</div>
</body>
angular.module('X').controller('app', function($rootScope, $route) {
$rootScope.$on('$routeChangeSuccess', function(){
$rootScope.containerClass = angular.lowercase(($route.current.controller || '').replace(/Ctrl$/, ''));
});
});

Resources