I have a index.html page and this page is working as a single directive.
angular.module('app').directive('index', function() {
return {
templateUrl: 'html/index.html'
}
}).controller('index', ['$scope', '$http', function($scope, $http) {}])
Inside index.html, I have three tabs gallery, list and summary. I have put all these three tabs in different directive like this.
/*Gallery directive*/
angular.module('app').directive('gallery', function() {
return {
templateUrl: 'html/gallery.html'
}
})
/*List directive*/
angular.module('app').directive('list', function() {
return {
templateUrl: 'html/list.html'
}
})
angular.module('app').directive('summary', function() {
return {
templateUrl: 'html/summary.html'
}
})
I want that when I load the index.html page the gallery and the summary directive should also get loaded and visible in index.html. Also I am fetching some data in index.html on load, I also want to pass that data to summary,gallery and list directives. Also I have a gallery tab and list tab. When I click on the gallery tab I want the gallery directive to be loaded and when I click on the list tab I want the list directive to be loaded with the data. Initially the gallery and the summary directive should be there by default. The switching will only happen in gallery and the list view. The summary directive should be fixed there.
Initially I developed it all in a single directive. But now I am trying to make all these in a different directive.
Image below explain about my scenario
I am not sure, can we call multiple directive through single directive ? If yes then how can I achieve this ?
Regards
Create a factory holding the data that gets injected to the directive
Here its shown Sharing data between directives
Related
I built a simple application that has a home page, a login page and a contacts page, based on the Ionic example on Codepen. My application is here. Login controller sets a $rootScope.user variable when we log in:
.controller('LoginCtrl', function($scope, $rootScope, $state) {
$scope.login = function(){
$rootScope.user = {name:"lyman"};
$state.go("tabs.contact");
};
})
After login we correctly get redirected to the Contacts screen, Contacts tab is shown and highlighted. Now click on the Home tab. Expected behavior: I should see the Home page saying I'm logged in. What I get: the title changes to Home, Home tab is highlighted, but the view changes to templates/login.html template! You can still navigate to Contacts, log out from there, and then navigation stops working altogether. What am I missing?
Another oddity is that ng-show and ng-hide directives are being completely ignored when trying to hide and show tabs, only ng-if works. I'm thinking maybe the issue is because I'm using ng-if to insert and remove tabs from the markup and with ion-nav-view residing inside of the ion-tab tab? What would be the workaround?
So, yes, using ng-if to hide/show tabs will screw up navigation. The solution is to use the tab's hidden property as demonstrated in this fork of my original example:
<ion-tab title="Log In" icon="ion-ios-person" ui-sref="tabs.login" hidden="{{ loggedIn() }}">
<ion-nav-view name="login-tab"></ion-nav-view>
</ion-tab>
Controller:
.controller('TabsCtrl', function($scope, $rootScope) {
$scope.loggedIn = function() {
if ($rootScope.user) {
return true;
}
return false;
};
})
I have a one page app which contains the ui.router AngularJS with multiple states links to different parts/code etc. The issue is that inside some of those state html pages I have for example a href="#tip" link that should open a modal that is part of a jQuery code; but what actually happens is that the State ends up changing and going back to my .otherwise("/") page in the state model.
I have noticed that what happens is that the link which is requested is not the correct link with the ui.router url that is currently rendering the page. For example, my app is on example.com/app .. When a state changes the url changes to example.com/app/#/page1 or page2 etc .. When a href="#" link is clicked, the link actually points to example.com/#link instead of what I assume should be example.com/#/page1/#tip or /#/tip considering the way my urls are shown..
How can I fix this to allow the href="#" tags to do and function as they originally did before being placed in states?
Below is my provider setup and a sample sate:
.config(function($stateProvider,$urlRouterProvider,$urlMatcherFactoryProvider){
$urlRouterProvider.otherwise('/app');
$urlMatcherFactoryProvider.strictMode(false)
$stateProvider
.state('flashcards', {
url: "/page1",
views: {
'input-views': {
templateUrl: '/page1.html',
}
}
})
});
I'm using the latest Ionic "nighty build" version currently.
One good news with this version is the concept of cached views:
By default views are cached to improve performance. When a view is
navigated away from, its element is left in the DOM, and its scope is
disconnected from the cycle. When navigating to a view which is
already cached, its scope is then reconnected, and the existing
element which was left in the DOM becomes the active view. This also
allows for scroll position of previous views to be maintained.
Interesting, so I tried it and it's really smooth.
However, I come across a severe UX issue:
Basically, my app is composed of 2 tabs.
TabA aims to display a load and list items.
TabB aims to display other items.
Each one has its own navigation: listing and showing specific items.
Obviously, the first time, data are fresh, but then, since cached => stale.
Cached views is really adapted to the "back" button from the "show" to the "list" of a specific tab.
Indeed, scroll is maintain and controllers don't need to reload => very good performance.
However, what a user wants when he clicks on a particular tab is to get a refreshed list.
I really can't find a pretty and efficient way to refresh a specific cached view regarding the clicked element.
I've got those declared states (showing the example for TabA):
.state('tab', {
url: "/tab",
abstract: true,
templateUrl: "/tabs.tpl.html",
controller: 'TabsCtrl'
})
.state('tab.tabAList', {
url: '/items',
views: {
'tab-a': {
templateUrl: '/tabAList.tpl.html',
controller: 'TabACtrl'
}
}
})
.state('tab.tabAShow', {
url: '/tabAList/:itemId',
views: {
'tab-a': {
templateUrl: '/tabAShow.tpl.html',
controller: 'TabAShowCtrl'
}
}
});
So, tab's controller is the parent of tab.tabAList and tab.tabAShow.
tabList contains a function like:
$scope.reloadItems = function() {
//...
}
How to trigger this function when tabA is clicked?
The tricky part is that TabsCtrl code is run just before nested TabAList controller is run.
I tried to involve a $rootScope.$broadcast('reloadTheItems',...) under the on-select attribute of the tab.
But the event is missed since tabAList hasn't run yet at the time of the event sending.
Has anyone experienced it and has a pretty solution?
I repeat, the goal is: "Reload a specific cached view on tab click".
You should listen to the $ionicView.enter event for the view for TabA.
Then do this from the $scope:
$scope.$on( "$ionicView.enter", function( scopes, states ) {
if( states.fromCache && states.stateName == "tab.tabAList" ) {
reloadItems();
}
});
...or something similar...
My application has several 'modal' windows, For now there is no specific route to reach an open modal directly. I mean, written the url directly in the browser.
There are a Jquery solution, but how implement some similar solution for angular? where placed? when should run?
You can perform this sort of task within the routing config of your app.
For example, this one is using ui-router, for the routes, and ui-bootstrap for the modals.
In the route config add an onEnter which will fire when the route is first entered.
.state('login', {
onEnter: function ($stateParams, $state, $modal) {
$modal.open({
keyboard: false, // prevents escape-key closing modal
backdrop: 'static', // prevents closing modal outside of the modal
templateUrl: '/views/login', // view to load
controller: 'LoginCtrl' // controller to handle
})
}
})
Now, when navigating to the, in this example, login page the route will open the modal for me.
I've created an accordion based on ngResource (for live/ajax data). All works fine, however the accordion flashes (twice) on loading. How can I stop this?
This is my code (service):
AdminMenu.factory('myServices', ['$resource', function($resource) {
return $resource('/api/categories?sort=createdAt asc');
}]);
And this is my template:
accordion(class="admin-accordion", close-others="accordion", ng-cloak)
accordion-group(ng-repeat="category in categories", is-open="category.active", heading="{{category.name}}")
tabset
tab(ng-repeat="subcat in category.subcategories", heading="{{subcat.name}}", active="subcat.active", select="alertMe(category.subcategories)") {{subcat.content}}
PS: I don't know whether it could be related but within my accordion, I also have a tab using the same data as the accordion (as you can see from example above)
Any ideas?