In my MVC 5 application I want to use some AngularJS. Now, I have a project card. You can call this card by following the url:
http://localhost/Project/Card/1
For this card, I have a list of projectTasks. Based on the id = 1 parameter I want AngularJS to show this list, but I don't know how to get the id parameter. I was looking at ngRoute, but I don't want to route I only want to construct a dynamic url in my ProjectTaskController.
What I have so far:
projectApp.js
(function () {
var app = angular.module("projectApp", ["ngRoute"]
.config(function ($routeProvider, $locationProvider) {
//configure the routing rules here
$routeProvider.when('/Card/:id', {
controller: 'ProjectTaskCtrl'
});
// enable HTML5mode to disable hashbang urls
$locationProvider.html5Mode(true);
})
}());
ProjectTask.js
(function (app) {
var projectTaskCtrl = function ($scope, $routeParams) {
alert($routeParams.id); // message: undefined
};
app.controller("ProjectTaskCtrl", projectTaskCtrl);
}(angular.module("projectApp")));
I've solved it by using ng-init:
in my MVC5 View (Show.cshtml) I added:
<div id="projectTasks" ng-app="ProjectApp">
<div ng-controller="ProjectTaskCtrl">
<input type="hidden" id="projectId" ng-model="projectId" ng-init="projectId=#ViewBag.projectId"/>
<!-- some more code -->
</div>
</div>
In my ProjectTaskCtrl.js:
(function (app) {
var projectTaskCtrl = function ($scope) {
$scope.$watch("projectId", function(){
// I can now use projectId in whatever I want:
alert($scope.projectId);
});
};
app.controller("ProjectTaskCtrl", projectTaskCtrl);
}(angular.module("projectApp")));
Related
I have written web application on .net 2017 c#, I had to change my URL to simpler in order to get rid of ? or = from URL and also I am using Google Map on my web site. When I click to records which will be redirected and changed to other link, I got this error.
Original url is: mydomain.com/Doctor?id=XX
I converted it to: mydomain.com/Doctor/XX
I did it by defining new MapRoute on RegisterRoutes as:
RouteCofig.cs:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Blog", // Route name
"Doctor/{id}", // URL with parameters
new { controller = "Home", action = "PersianDR", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
I also used angularjs:
Angular Module:
var app = angular.module('MyApp', ['ngRoute', 'uiGmapgoogle-maps', 'nemLogging', 'ngSanitize']);
app.config(['$routeProvider', '$locationProvider', function ($routeprovider, $locationProvider) {
$routeprovider.
when('/Home/PersianDR/:id', {
templateurl: '/Views/Home/PersianDR.cshtml',
controller: 'AngularCtrl_ShowDr'
})
.
when('Doctor/:id', {
redirectto: '/Home/PersianDR/:id'
})
.
otherwise({
redirectto: '/'
})
;
//$locationProvider.html5Mode(true);
$locationProvider.html5Mode({
enabled: true,
rewriteLinks: false
});
}]);
Angular Controller:
app.controller("AngularCtrl_ShowDr", function ($scope, $location, angularService_ShowDr, $route, $routeParams, $http, $sce) {
var docId = $("#myId").val();
$location.path();
$location.url('Doctor/' + docId).replace();
GetDoctorByID();
GetGeoCoordinates();
maps();
});
This problem as been started since I changed URL.
I finally found an interesting answer.
There is a conflict when I wanted to redirect and make my url simple while I am using google map apis, this is because gmap needs absolute path or url while I wanted to change my url simple and elegant.
What I did to remove holding on waiting to load csi.gstatic.com, was to use partial view.
I totally brought my ui-gmap-google-map inside partial view and called it from original one.
In original page.cshtml:
#Html.Partial("_MapDoctor")
In partial view , _MapDoctor.cshtml:
<div ng-controller="AngularCtrl_MapDr">
<input type="hidden" id="myId2" value="#ViewBag.id" />
<ui-gmap-google-map center='mapsdrsec.center' zoom='mapsdrsec.zoom' options='mapsdrsec.options'>
<ui-gmap-layer type="TrafficLayer" show="mapsdrsec.showTraficLayer"></ui-gmap-layer>
<ui-gmap-markers models="markers" idkey="markers.id" coords="'coords'">
</ui-gmap-markers>
</ui-gmap-google-map>
</div>
I wrote specified controller and services in angularjs for partial view. I deleted filling $scope.map from original and wrote (center, zoom, options, $scope.markers ) in partial view controller.
I'm developing in DNN 8.0 with its new SPA framework.
I'm using angularjs instead of the defaulted KnockOut.
When I put module setup code in view.html, it works fine. But it doesn't work if I try to put the code in a different file, say app.js. Anyone has seen this before?
A snap shot of the view.html that works looks like this:
[JavaScript:{ jsname: "JQuery" }]
[JavaScript:{ path: "~/Resources/Shared/scripts/dnn.jquery.js"}]
[JavaScript:{ path: "~/DesktopModules/DNNSPA/Scripts/angular.js"}]
[JavaScript:{ path: "~/DesktopModules/MyApp/Scripts/angular-route.js"}]
[JavaScript:{ path: "~/DesktopModules/MyApp/ngApp/app.js"}]
[JavaScript:{ path: "~/DesktopModules/MyApp/ngApp/ngControllers/FirstController.js"}]
[CSS:{ path: "~/DesktopModules/MyApp/CSS/bootstrap.min.css"}]
<script type="text/javascript">
var d = new Date();
var moduleId = parseInt("[ModuleContext:ModuleId]");
var portalId = parseInt("[ModuleContext:PortalId]");
var sf = $.ServicesFramework(moduleId);
var moduleName = "MyApp";
if ("[ModuleContext:EditMode]" === 'True') {
var editMode = true;
}
console.log(editMode);
var currentDate = d;
var app = angular
.module('dnnapp', [
'ngRoute'
])
.config(
function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: '/DesktopModules/MyApp/partials/firstView.html',
controller: 'firstController'
});
});
app.controller('firstController', function ($scope, $http) {
// controller code
});
</script>
<div class="module-wrap" ng-view>
</div>
All setup code is in view.html.
But if I move the module definition to app.js and controller definition to FirstController.js, it doesn't work.
I've seen others make it work in different files, what am I doing wrong here?
The SPA tokens, ie: [ModuleContext:ModuleId] will not get replaced in your .js file. Therefore you need to do some setup work for your angular module on the page and move all the rest to a js file. Here is one technique:
On your View.html, define an html element for your angular app with an ng-init() method:
<div id='dnnuclear-item-[ModuleContext:ModuleId]' ng-controller="ItemController"
ng-init="init([ModuleContext:ModuleId],'[ModuleContext:ModuleName]','[ModuleContext:EditMode]')">
...
</div>
Also on your View.html, bootstrap your angular app:
<script type="text/javascript">
angular.element(document).ready(function () {
var moduleContainer = document.getElementById('dnnuclear-item-[ModuleContext:ModuleId]');
angular.bootstrap(moduleContainer, ["dnnuclear.ItemApp"]);
});
</script>
Then in your .js file, define the angular module and controller with the init method implementation:
var dnnuclear = dnnuclear || {};
dnnuclear.ItemApp = angular.module("dnnuclear.ItemApp", ['ngDialog']);
dnnuclear.ItemApp.controller("ItemController", function ($scope, $window, $log, ngDialog, dnnServiceClient) {
...
$scope.init = function (moduleId, moduleName, editable) {
$scope.ModuleId = moduleId;
$scope.EditMode = editable;
dnnServiceClient.init(moduleId, moduleName);
$scope.getAll();
}
}
If you need to pass more information to the module than a few variables, I would recommend changing this approach. I have more on this in my DNNHero.com tutorial, Advanced Angular Concepts.
You should try the AngularDNN module. It will probably save your time. It can be found here:
http://store.dnnsoftware.com/home/product-details/angulardnn
I have a text field:
<input type="text" ng-model="user">
and I have a button that will redirect to another page. On that page, I want to print the username typed in by the user. How can I do that?
My preference is ionic.
ionic works on top of angular. There are various ways by which you can achieve this functionality:
1) Use constants file to keep your value
Create a file called constants.js, include it in your index.html as:
<script src="Constants/Constants.js"></script>
declare key value pair combinations in it as:
var url_config = {
"USER_NAME" : "LOGIN_USER",
};
in your controller file, set the USER_NAME value as:
url_config.USER_NAME = $scope.user; //the model variable name that you had used
Use this value, where you want to access as:
$scope.loggedInUser = url_config.USER_NAME; // you will get the value here
The disadvantage here is that the value will get lost if you reload the screen. This can be ignored in android or ios app that you create using phonegap, the screens can't be refreshed, but if you are using web app this won't be a recommendable method.
2) Use a service to pass the constants
Create a utility service to keep the variable
angular.module('myApp').service('UtilityService', function () {
this.USER_NAME = '';
});
You can set this in your controller as:
angular.module('myApp')
.controller('LoginController', function ($scope, UtilityService) {
UtilityService.USER_NAME = $scope.user;
});
Access it in your other controller as:
angular.module('myApp')
.controller('UserController', function ($scope, UtilityService) {
$scope.loggedInUser = UtilityService.user;
});
This is a reliable way and a recommended method too.
3) Use local Storage
Here you can use the HTML5 feature of local storage to access the value from the browser's local storage.
Set the value in the login controller as:
angular.module('myApp')
.controller('LoginController', function ($scope, $localStorage) {
$localStorage.USER_NAME = $scope.loggedInUser;
});
In the receiving controller use it as:
angular.module('myApp')
.controller('UserController', function ($scope, $localStorage) {
$scope.loggedInUser = $localStorage.USER_NAME;
});
This will pertain the value even if the app goes to background or quits. Unless you clear the app cache or app data manually, the value will be saved.
For accessing $localStorage, you will require to use the ngStorage plugin that you can access from github and follow the instructions for instalation, then inject ngStorage as:
var myApp = angular.module('app', ['ngStorage']);
Now you are ready to use the $localStorage, provided you have included it in the controller where you are willing to access it.
4) Use session storage
Using the same ngStorage plugin you can use the session storage via $sessionStorage.
Set the value in the login controller as:
angular.module('myApp')
.controller('LoginController', function ($scope, $sessionStorage) {
$sessionStorage.USER_NAME = $scope.loggedInUser;
});
In the receiving controller use it as:
angular.module('myApp')
.controller('UserController', function ($scope, $sessionStorage) {
$scope.loggedInUser = $sessionStorage.USER_NAME;
});
Session storage keeps the data in session which gets expired after a limited time. This usage would be recommended for features like access tokens etc. For this scenario of username this won't be a recommended method
There are mainly two ways to achieve this:
1.By using Constants
app.js
angular.module('ionicApp', ['ionic'])
.constant('appConstant', {
user: ''
})
Controller
angular.module('ionicApp.home', ['ionic'])
.controller('homeCtrl', ['$state', 'appConstant', function($state, appConstant) {
'use strict';
$scope.user = '';
$scope.onClick = function() {
appConstant.user = $scope.user;
};
}]);
html
<input type="text" ng-model="user">
<button ng-click="onClick()">Submit</button>
Now you will get user name from any controllers by using appConstant.user
2.By using localstorage
Controller
angular.module('ionicApp.home', ['ionic'])
.controller('homeCtrl', ['$state', '$localStorage', function($state, $localStorage) {
'use strict';
$scope.user='';
$scope.onClick = function() {
$localStorage.set('user', user);
};
}]);
html
<input type="text" ng-model="user">
<button ng-click="onClick()">Submit</button>
Now you will get user name from any controllers by using $localStorage.get('user')
I am using Angular and I need to define routing in ng-route config but also in my services to be used by $http in services methods.
The problem is that the route strings change in my application according to language ... For example for an about us page I might have:
"en/about-us", "pt/quem-somos", "fr/ ..."
The application has a RouteProvider that returns route strings by key.
The idea would be to create a script on the fly for a service that injected in angular components would allow to get those routes strings.
<script type="text/javascript">
// Create $routes service using backend code ...
</script>
This would be used on app.config as follows:
app.config(['$routeProvider', function($routeProvider, $routes) {
$routeProvider.
when($routes.getByKey('about.home', {
templateUrl: 'about/home.html',
controller: 'AboutController'
})
}
But also in a service as follows:
application.service('CountryService', function ($http, $routes) {
return {
GetList: function () {
return $http.get($routes.getByKey('api.countries.list');
}
}
});
My problem is how to write the JS part of such a service and to plug it into angular components. Is it possible to create such a service?
I would not conflate view routes from the API endpoints - these are different creatures.
And you don't need to create a route per language - just use language as a parameter:
$routeProvider
.when("/:lang/about-us", {
template: "<h3>About Us</h3> in lang: {{language}}",
controller: function($scope, $routeParams, $location){
$scope.language = $routeParams.lang;
}
})
.when("/:lang/something-else", {
template: "<h3>Something Else</h3> in lang: {{language}}",
controller: function($scope, $routeParams){
$scope.language = $routeParams.lang;
}
})
plunker
How I can use On demand loading of controllers /services in angularJs. now I have a mainApp which referenced by Index.html. I am using $routeprovider to routing but all the required controller/services are referenced in the corresponding views eg:
<section id="pageLevelScripts">
<!--location of page level scripts-->
<script src="/Area/Sotaria/Controllers/UserController.js"></script>
</section>
<div class="row" >
<div class="col-lg-12">
<div class="row">
<div class="col-lg-12">
<ol class="breadcrumb">
<li>Home</li>
<li>Usermanagement</li>
<li class="active"><span>Users</span></li>
</ol>
<h6>{{name}}</h6>
</div>
</div>
This is my requirement I don't want to load all the controllers in my Index.html. but when I navigate to the childView, I am getting an error "Usercontroller is undefined", So how I can enable ondemanidng / lazy loading of controllers in angualrjs, .Ie. when ever the child page loaded ,then only its related controllers should load.
The reason you get undefined is because just loading the JS file doesn't make Angular aware of it. You must attach it to Angular's $controllerProvider.
You can create a custom service that does the lazy loading for you or use one of the many already built by other people. Here is an example of a custom one that you can use with requirejs.
If the below example is not explanatory enough you can read this blog post here: Strange Milk - Front End Development
Custom Provider
function LoaderProvider(){
this.controller = null;
this.directive = null;
this.filter = null;
this.factory = null;
this.service = null;
//service factory definition
this.$get = ['$q', '$rootScope', function($q, $rootScope){
return {
load: function (path) {
var q = $q.defer();
require([path], function () {
$rootScope.$apply(function () {
q.resolve();
});
});
return q.promise;
}
};
}];
}
var container = new LoaderProvider();
module.provider('Loader', function(){
return container;
});
Your Apps config:
.config(function (LoaderProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) {
// save references to the providers
LoaderProvider.controller = $controllerProvider.register;
LoaderProvider.directive = $compileProvider.directive;
LoaderProvider.filter = $filterProvider.register;
LoaderProvider.factory = $provide.factory;
LoaderProvider.service = $provide.service;
})
An example of how you would use this in your App's routes. Learn more about Resolve
resolve : {
load : ['Loader', function(Loader){
return Loader.load('../app/global/controllers/headerCtrl');
}]
}
Some other resources/solutions:
ocLazyLoad
angularAMD