Template does not load angular js - javascript

I'd like to load a template using Angular controller. I have created everything needed:
routes.config.js
index.component.js
index.config ( here is the config of the parent controller )
html
js controller
connected with php controller
I already created templates and controllers exactly the same way and I have no idea what am I doing wrong. It's interesting that when I open elements tab in the browser I can see the <statistic-test></statistic-test> tags, and url also change. If I change <statistic-test></statistic-test> to another tag which is already used in another controller then it loads.
test-question.component.js
class TestQuestionController{
constructor($scope, $state,$stateParams, $compile, DTOptionsBuilder, DTColumnBuilder, API){
'ngInject';
this.API = API
this.$state = $state
if ($stateParams.mode) {
this.mode=$stateParams.mode
}
let Statics = API.service('show', API.all('statisticQuestion'))
this.userlistaction = "app.statisticanswer.userlist"
}
$onInit(){}
}
export const TestQuestionComponent = {
templateUrl: './views/app/components/statistic-question-userlist/test-question.component.html',
controller: TestQuestionController,
controllerAs: 'vm',
bindings: {}
}
I also have an html named test-question.component.html
routes.config.statistic.question.js
export function RoutesConfigStatisticQuestion ($stateProvider) {
'ngInject'
$stateProvider
.state('app.statisticquestion', {
url: '/statistic-question',
data: {
auth: true
},
views: {
'main#app': {
template: '<statistic-question></statistic-question>'
}
},
ncyBreadcrumb: {
label: 'Kérdések statisztika',
}
})
.state('app.statisticquestion.test', {
url: '/statistic-test/',
data: {
auth: true
},
views: {
'main#app': {
template: '<statistic-test></statistic-test>'
}
},
params: {
contentsId : null,
alerts: null
},
ncyBreadcrumb: {
label: 'Címke szerkesztése',
parent: 'app.statisticquestion'
}
})
If you have ANY idea how to solve this please share it with me.

Related

A parameter of ui-router in controller and resolve

I have configured the following ui-router.
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('global.editor', {
url: '/posts/editor/{id}',
templateUrl: '/htmls/editor.html',
controller: 'EditorCtrl',
resolve: {
post: ['$stateParams', 'codeService', function ($stateParams, codeService) {
return codeService.getPost($stateParams.id)
}]
}
}
.state('global.new', {
url: '/new',
templateUrl: '/htmls/editor.html',
controller: 'EditorCtrl'
})
.state('global.newTRUE', {
url: '/newTRUE',
templateUrl: '/htmls/editor.html',
controller: 'EditorCtrl'
})
.state('global.editor.panels', {
controller: 'PanelsCtrl',
params: { layout: 'horizontal' },
templateUrl: function (params) { return "/htmls/" + params.layout + '.html' }
}
}])
app.controller('EditorCtrl', ['$scope', '$state', function ($scope, $state) {
$scope.layout = "horizontal";
$scope.$watch('layout', function () {
$state.go('global.editor.panels', { layout: $scope.layout });
});
}]);
As a result, https://localhost:3000/#/new in a browser leads to (the state global.editor, then to) the state global.editor.panels.
Now, I want to add a parameter connected:
I don't want it to be shown in the url
https://localhost:3000/#/new in a browser makes connected to be false, and https://localhost:3000/#/newTRUE in a browser makes connected to be true
connected can be past into the controller EditorCtrl and PanelsCtrl
connected can be available in the resolve of global.editor; ideally, we could resolve different objects according to the value of connected.
Does anyone know how to accomplish this?
You can add resolve for new and newTRUE:
.state('global.new', {
url: '/new',
templateUrl: '/htmls/editor.html',
resolve: {
isConnected: function() {
return false;
}
},
controller: 'EditorCtrl'
})
.state('global.newTRUE', {
url: '/newTRUE',
templateUrl: '/htmls/editor.html',
resolve: {
isConnected: function() {
return true;
}
},
controller: 'EditorCtrl'
})
And in EditorCtrl (or PanelsCtrl) you can use it like:
app.controller('EditorCtrl', ['$scope', '$state', 'isConnected', function($scope, $state, isConnected) {
console.log("connected : " + isConnected); // you can save this value in Service and use it later.
...
}]);
You can use classic approach - in resolve
Or you can use hidden parameters from angular ui router.
Define params : {isConnected' : null} in your parent global state.
In:
global.newTRUE - set value in $state config
global.new - set value in $state config
global.editor.panels - set parameters in transition/go or ui-sref
definition is like this:
$stateProvider
.state('global.newTRUE', {
url : '/:newTRUE',
params : {
'isConnected' : false
}
});
}
and in controller you get in from $stateParams.
Problem with this approach is hidden parameters are loses in refresh page, except if is set default value
You can surely use the params of UI-Router states' config to not show it in URL and achieve all mentioned points.
Also, as per #2, you need connected to be false for /new and true for /newTRUE. We can do so by passing true or false as default value for those states. Something like this:
$stateProvider
.state('global.editor', {
url: '/posts/editor/{id}',
templateUrl: '/htmls/editor.html',
params: { connected: null },
controller: 'EditorCtrl',
resolve: {
post: ['$stateParams', 'codeService', function ($stateParams, codeService) {
return codeService.getPost($stateParams.id)
}]
}
}
.state('global.new', {
url: '/new',
templateUrl: '/htmls/editor.html',
params: { connected: false }, // default false for /new
controller: 'EditorCtrl'
})
.state('global.newTRUE', {
url: '/newTRUE',
templateUrl: '/htmls/editor.html',
params: { connected: true }, // default true for /newTRUE
controller: 'EditorCtrl'
})
.state('global.editor.panels', {
controller: 'PanelsCtrl',
params: { layout: 'horizontal', connected: null },
templateUrl: function (params) { return "/htmls/" + params.layout + '.html' }
}
For #3, In order to access connected in your controllers (EditorCtrl and PanelsCtrl) you can inject $stateParams to controller and use $stateParams.connected to get it.
For #4, (This is more or less similar to achieveing #3)
Just like you get $stateParams.id, you can have $stateParams.connected as well, which you can use to resolve different objects according to the value of connected. Something like this:
.state('global.editor', {
url: '/posts/editor/{id}',
templateUrl: '/htmls/editor.html',
params: { connected: null },
controller: 'EditorCtrl',
resolve: {
post: ['$stateParams', 'codeService', function ($stateParams, codeService) {
return $stateParams.connected ?
codeService.getPost($stateParams.id) :
codeService.getSomethingElse($stateParams.id)
}]
}
}
But, for that to work, make sure that you are passing connected as params when you visit global.editor state (using $state.go or ui-sref)
Hope this helps!

Sub view for $state not rendering in named ui-view

https://plnkr.co/edit/VV13ty8XaQ20tdqibmFy?p=preview
Expected
After login the dashboard state renders dashboard.html, and all components and ui-views should render: tickers, tags, social(named ui-view) and feed.
Results
After login the dashboard state renders dashboard.html however only the components tickers,tags and feed show up, but not the social (named-ui-view)
I feel that my problem lies somewhere around where I transition from the login state to the dashboard state. Once you hit the dashboard state, it serves up the default template which is the component element tag: <dash-module></dash-module>. This will then render the dash.component template: dashboard.html and controller. However I've lost access to the social view in the dashboard state object.
dashboard.html
<div class="jumbotron text-center">
<h1>The Dashboard</h1>
</div>
<div class="row">
<tickers-module></tickers-module>
<tags-module></tags-module>
// Expecting the social-module-template.html to show below:
<div ui-view="social"></div>
<feed-module></feed-module>
</div>
The routerApp module with the dashboard component full code in Plnkr
// RouterApp module
////////////////////////////////////////////////////////////////////////////////
var routerApp = angular.module('routerApp', ['ui.router', 'tickers', 'tags', 'feed']);
routerApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
const login = {
name: 'login',
url: '/login',
templateUrl: 'login.html',
bindToController: true,
controllerAs: 'l',
controller: function($state) {
this.login = function() {
$state.go('dashboard', {});
}
}
}
const dashboard = {
name: 'dashboard',
url: '/dashboard',
params: {
ticker: {},
tags: {}
},
template: '<dash-module></dash-module>',
views: {
'' : {
templateUrl: 'dashboard.html',
},
'social' : {
templateUrl: 'social-module-template.html',
controller: function($state) {
console.log('Social init', $state.params);
}
}
}
}
$stateProvider
.state(login)
.state(dashboard);
})
tags.component('dashModule', {
templateUrl: 'dashboard.html',
controller: function($scope, $state) {
console.log('dashModule loaded!');
}
})
This is the part that should render the social html content in the <div ui-view="social"></div>
views: {
'' : {
templateUrl: 'dashboard.html',
},
'social' : {
templateUrl: 'social-module-template.html',
controller: function($state) {
console.log('Social init', $state.params);
}
}
}
I made changes to your plunker here You were missing # here.
const dashboard = {
name: 'dashboard',
url: '/dashboard',
params: {
ticker: {},
tags: {}
},
template: '<dash-module></dash-module>',
views: {
'' : {
templateUrl: 'dashboard.html',
},
'social#dashboard' : {
templateUrl: 'social-module-template.html',
controller: function($state) {
console.log('Social init', $state.params);
}
}
}
}
In order for these components to appear under the home state, we must define them using absolute naming. Specifically, we must use the # syntax to tell AngularJS that these components of our application should be mapped to a specific state. This follows the viewName#stateName syntax and tells our application to utilize named views from an absolute, or specific state. You can read more about relative vs. absolute names here.
See this for more information.
The problem you have is named view has to render in same state i.e Dashboard.
Change the following and it should work.
social#dashboard
Check this Plunkr
Named Views UI router

Angular ui-router named views abstract controller not fireing

It seems that having a controller in an abstract named view will not fire that controller when a child view also implements a controller, only the child controller fires. My setup is as follows:
$stateProvider
.state('app', {
abstract: true,
views : {
header: {
template: "<p>My header</p>"
},
section: {
template: "<ui-view />",
controller: function () {
alert('loaded main control');
}
}
}
})
.state('app.home', {
url: '',
views: {
'section#': {
template: "<p> My initial content here </p>",
controller: function () {
alert("loaded home control");
}
}
}
})
http://plnkr.co/edit/WjUYwEfrNbZrdpUQAole?p=preview
In my mind the above demo should trigger both alerts, why is this not happening?
In the app.home you are using the section# as the view name, which is an absolute match, and then is conflicting with the section view defined in the abstract app state.
In fact, the first section view appears to be useless. You can try the following snippet.
$stateProvider
.state('app', {
abstract: true,
views : {
header: {
template: "<p>My header</p>",
controller: function () {
alert("loaded main control");
}
}
}
})
.state('app.home', {
url: '',
views: {
'section#': {
template: "<p> My initial content here </p>",
controller: function () {
alert("loaded home control");
}
}
}
})
More details available in the Multiple Named Views section of the ui-router guide.

AngularJS ui-router navigating states with $state.params and queries

I have an app with multiple states that each have nested views. The one state has a conditional templateUrl, and based on a $state.param will show specific HTML/JS. I want to set a query on the URL of the state, so that I know which list item is being looked at when I click it. I cannot figure out how to set a url query and transition to the desired state's view.
My states:
.state('index', {
url: '/',
views: {
'#' : {
templateUrl: 'views/layout.html'
},
'top#index' : {
templateUrl: 'views/top.html',
controller: function($scope, $state) {
$scope.logOut = function() {
$state.go('login');
};
}
},
'left#index' : { templateUrl: 'views/left.html' },
'main#index' : { templateUrl: 'views/main.html' }
}
})
.state('index.list', {
url: 'list?item',
templateUrl: 'views/lists/list.html',
controller: 'ListCtrl'
})
.state('index.list.details', {
url: '/',
params: {
detail: 'overview'
},
controller: ctrl,
views: {
'details#index' : {
templateUrl: function($stateParams) {
if($stateParams.detail === 'status' ) {
ctrl = 'StatusCtrl';
return 'views/details/status.html';
} else if ($stateParams.detail === 'overview') {
ctrl = 'OverviewCtrl';
return 'views/details/overview.html';
}
}
}
},
})
In my controller for the index.list, this is where I have the list and click and populate the details view.
HTML & Js:
<div class="channel" ng-repeat="item in items" ng-click="viewListDetails(item)">
$scope.viewListDetails = function(item) {
$location.search('item', item.id);
$state.go('index.list.details', {detail: 'status'}, {reload: true})
};
My JS above runs the through the function however it does nothing! It will not set the query or transition to the desired view for that sate.
Any help is appreciated!
index.deviceList.detail is not a defined state. You probably intended to write index.list.details.

Angular UI-Router - using "resolve" directly on template url

I am using UI-Router and want to change routing to be 'component based'. So Instead of defining a controller / template I want to use it like this:
.state('issue', {
url: '/someUrl/:number',
template: '<my-directive></my-directive>',
resolve: {
data: function(dataService) {
return dataService.getData().then(function(response) {
console.log(response.data);
return response.data;
});
}
}
})
Now, I know that with Angular's ngRoute I can use resolved data directly in the template, for example:
$routeProvider
.when('/', {
template: `<my-directive data="resolve.data"></my-directive>`,
resolve: {
data: function (dataService) {
return dataService.getData();
}
}
})
I couldn't do it using UI-Router (value was undefined).
Am I doing something wrong? Is it possible using ui-router?
The point with UI-Router is - result of resolve is available for a controller (related to template). So, we could do it like this:
.state('issue', {
url: '/someUrl/:number',
template: '<my-directive data="stateCtrlData"></my-directive>',
controller: function($scope, data) { $scope.stateCtrlData = data },
resolve: {
data: function(dataService) {
return dataService.getData().then(function(response) {
console.log(response.data);
return response.data;
});
}
}
})
The data are passed into controller and from its scope we pass it to directive.
If you mean injecting your data service, then you can do it like this (remember that the '' is telling to inject):
state('issue', {
url: '/someUrl/',
template: '<my-directive data="pep.data"></my-directive>',
controller: function( data) { this.data = data },
controllerAs: 'pep',
resolve:{
dataSvc : 'YourDataSvc',
campaign : function(dataSvc){
return dataSvc.getData();
}
}
Please remember a ui-view will be expected if you want to put additional views or child states.
Actually you can (tested only in ui-router v0.3.2)
There's an undocumented $resolve variable which is automatically injected in the controller.
Simply add 'controllerAs' property to the state as follows, and you can use $resolve in the template:
.state('issue', {
url: '/someUrl/:number',
template: '<my-directive data="vm.$resolve.data"></my-directive>',
controllerAs: 'vm',
resolve: {
data: function(dataService) {
return dataService.getData().then(function(response) {
console.log(response.data);
return response.data;
});
}
}
})

Categories

Resources