Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Two complex problems with our tabs directive
Message
De
11/11/2015 04:15:02
 
 
Information générale
Forum:
Javascript
Catégorie:
Autre
Divers
Thread ID:
01627325
Message ID:
01627326
Vues:
33
>Hi everybody,
>
>My colleague created these directives:
>
>
>(function () {
>
>    'use strict';
>
>    var app = angular.module('sysMgrApp')
>    .directive('smNavTabs', ['$rootScope', '$location', '$state', '$stateParams', navTabViews])
>    .directive('smNavTab', ['$rootScope', '$location', '$state', '$stateParams', navTabView]);
>
>    function navTabViews($rootScope, $location, $state, $stateParams) {
>        return {
>            restrict: 'E',
>            transclude: true,
>            replace: true,
>            scope: {},
>            controller: function ($scope) {
>                $rootScope.$state = $state;
>                $rootScope.$stateParams = $stateParams;
>
>                $rootScope.stateChangeAborted = false;
>
>                var urlProtocolAndPath = $location.protocol() + '://' + $location.host() + ($location.port() != NaN ? ':' + $location.port() : '');
>
>                var panes = $scope.panes = [];
>
>                $scope.select = function (uiView) {
>
>                    // call hook before changing state
>                    uiView.onActivating(uiView.name);
>                   
>                    // use $rootScope to make call to change the state
>                    $rootScope.$state.go(uiView.name, uiView.viewSettings.params, uiView.viewSettings.options);                    
>
>                    // set first call from 'addPane' function
>                    // to default tab
>                    if (panes.length === 0 && uiView.isVisible != false) {
>                        uiView.isActive = true;
>                    }
>                };
>
>                // called from $stateNotFound, $stateChangeError, $stateChangeAborted
>                // and $stateChangeSuccess event listeners
>                $rootScope.setNavTabs = function (viewName) {
>                    var i = 0;
>
>                    for (i = 0; i < panes.length; i++) {
>                        var pane = panes[i];
>
>                        // set to 'false' all but matching name
>                        pane.isActive = false;
>                        if ((pane.name == viewName)) {
>
>                            // recall hook if stateChangeAborted = true
>                            if ($rootScope.stateChangeAborted == true)
>                                pane.onActivating(viewName);
>
>                            pane.isActive = true;
>                        }
>                    }
>                }
>
>                //onStateChangeStart
>                $rootScope.$on('$stateChangeStart',
>                function (event, toState, toParams, fromState, fromParams) {
>                    // reset stateChangeAborted flag
>                    $rootScope.stateChangeAborted = false;
>                })
>
>                //onStateNotFound
>                $rootScope.$on('$stateNotFound',
>                function (event, unfoundState, fromState, fromParams) {
>                    $rootScope.stateChangeAborted = true;
>                    $rootScope.setNavTabs(fromState.name);
>                })
>
>                //onStateChangeError'
>                $rootScope.$on('$stateChangeError',
>                function (event, toState, toParams, fromState, fromParams) {
>                    $rootScope.stateChangeAborted = true;
>                    $rootScope.setNavTabs(fromState.name);
>                })
>
>                //onStateChangeAborted
>                $rootScope.$on('$stateChangeAborted',
>                function (event, toState, toParams, fromState, fromParams) {
>                    $rootScope.stateChangeAborted = true;
>                    $rootScope.setNavTabs(fromState.name);
>                })
>
>                //onStateChangeSuccess
>                $rootScope.$on('$stateChangeSuccess',
>                function (event, toState, toParams, fromState, fromParams) {
>                    $rootScope.stateChangeAborted = false;
>                    $rootScope.setNavTabs(toState.name);
>                })
>
>                this.addPane = function (pane) {
>                    if (panes.length === 0) {
>                        $scope.select(pane);
>                    }
>                    panes.push(pane);
>                };
>            },
>            templateUrl: 'app/templates/smNavTabs'
>        };
>    };
>
>    function navTabView($rootScope, $state, $stateParams) {
>        return {
>            require: '^smNavTabs',
>            restrict: 'E',
>            transclude: false,
>            replace: true,
>            scope: {
>                name: '@',
>                title: '@',
>                viewSettings: '@?',
>                onActivating: '&?',
>                isVisible: '=?'
>            },
>            link: function (scope, element, attrs, tabsCtrl) {
>
>                //default settings and functions
>                var defaultViewSettings = function () {
>                    var params, options;
>                    params = {};
>                    options = {
>                        location: true,
>                        inherit: true,
>                        relative: $state.$current,
>                        notify: true,
>                        reload: false
>                    };
>
>                    return {
>                        params: params,
>                        options: options
>                    };
>                };
>
>                var defaultOnActivating = function () {
>
>                };
>                scope.isVisible = scope.isVisible || true;
>                scope.viewSettings = scope.viewSettings || defaultViewSettings();
>                scope.onActivating = scope.onActivating || defaultOnActivating();
>
>                tabsCtrl.addPane(scope);
>            },
>        };
>    };
>
>})()
>
>with the template
>
>
><div class="tabbable">
>    <ul class="nav nav-pills nav-stacked">
>        <li ng-repeat="pane in panes" ng-class="{active:pane.isActive}" ng-show="pane.isVisible">
>            <a href="" ng-click="select(pane)" >{{pane.title}}</a>
>        </li>
>    </ul>
>    <div class="tab-content" ng-transclude></div>
></div>
>
>There are, unfortunately, two problems which I don't know how to solve.
>
>1. The invalid tab needs to show in red. This is how it is done in "static" case:
>
>
>ng-class="{true: 'invalid-tab', false: ''}[form.UserDefinedFields.$invalid]">
>
>More importantly, the invalid tab is not propagating to the whole form and I don't know how to make it work. Say, the first page will show several required columns in red, the Add (Save) button will be disabled. Switching to different tab activates that Add / Save button as the invalid state is not carried over.
>
>2. Similar problem seems to exist with the dirty state which is not propagating to the form. Making control dirty on some tab, then trying to navigate to a different row in the index list doesn't trigger 'Cancel changes' question. I had custom solution but I removed it as I want something generic.
>
>I think both problems can be somehow solved (e.g. saving the current form's state before switching over and restoring), but I don't see a way to access the form from the tab.
>
>Thanks in advance.

Not easy to see the problem amongst so much code without a runnable example. But it seems to me that this isn't really a 'Tab' control. You just have a set of buttons that inject the relevant view into the same area using $state.go. This means that when you go to any 'Tab' the view state of the existing view is lost.

It would be better if each tab had its own content which is shown or hidden depending on whether it is 'active'
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform