Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Scope problem
Message
 
 
General information
Forum:
Javascript
Category:
Other
Title:
Miscellaneous
Thread ID:
01627559
Message ID:
01627610
Views:
30
>>>Can you not use isolated scope, pass in the panes collection to be used and assign that the 'panes' - simple example : http://jsfiddle.net/joshdmiller/fhvd9/
>>
>>That means complete re-design again and going back to what I had originally. But sounds like it may be a good thing and we eventually switch to that.
>
>Hmm. You don't show (in your directive) how 'panes' is actually populated at present but I don't see how it would require a major change?

Here is the whole code for the directives and how it's currently used:
(function () {

    'use strict';

    var app = angular.module('sysMgrApp')
    .directive('smNavTabs', ['$rootScope', '$location', '$state', '$stateParams', navTabViews])
    .directive('smNavTab', ['$rootScope', '$location', '$state', '$stateParams', navTabView])
    .directive('smNavTabValidate', ['$rootScope', navTabViewValid]);

    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;
                $rootScope.currentNavTab = {};             
                if ($scope.panes == undefined) {
                    window.console && console.log('$scope.panes undefined, defining now...');
                    $scope.panes = [];
                }

                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;
              //      window.console && console.log('Method setNavTabs called with ' + viewName);
                    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);
                            }
                            window.console && console.log('Activating ' + viewName);
                            pane.isActive = true;
                            $rootScope.currentNavTab = pane;
                        }
                    }
                }

                //onStateChangeStart
                $rootScope.$on('$stateChangeStart',
                function (event, toState, toParams, fromState, fromParams) {
                    // reset stateChangeAborted flag
                    $rootScope.stateChangeAborted = false;

                    // Check if current smNavTab is Valid
                    //if ($rootScope.currentNavTab && $rootScope.currentNavTab.isValid == false) {
                    //    event.preventDefault();

                    //    $rootScope.stateChangeAborted = true;
                    //    $rootScope.setNavTabs(fromState.name);
                    //};
                })

                //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;
                    if (toState!=fromState)
                        $rootScope.setNavTabs(toState.name);
                })

                this.addPane = function (pane) {
                    window.console && console.log('Adding pane ' + pane.name + ' out of ' + panes.length + ' panes');
                    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.isValid = true;
                scope.isVisible = scope.isVisible || true;
                scope.viewSettings = scope.viewSettings || defaultViewSettings();
                scope.onActivating = scope.onActivating || defaultOnActivating();
               
                tabsCtrl.addPane(scope);
            },
        };
    };

    function navTabViewValid($rootScope) {
        return {
            require: ['^form'],
            restrict: 'A',
            link: function (scope, element, attrs, ctrl) {

                var form = ctrl[0];

                if (scope.$parent) {
                    if (scope.$parent.invalidTabs == undefined)
                        scope.$parent.invalidTabs = 0;
                }
                scope.$watch(
                    'form.$invalid',
                    function (newValue, oldValue) {

                        if (newValue != oldValue) {
                            if (newValue === true) {
                                $rootScope.currentNavTab.isValid = false;
                                scope.$parent.invalidTabs++;
                          //      window.console && console.log($rootScope.currentNavTab.name + ' tab is invalid; scope.invalidTabs =' + scope.$parent.invalidTabs);
                            };
                            if (newValue === false) {
                                $rootScope.currentNavTab.isValid = true;
                                scope.$parent.invalidTabs--;
                            //    window.console && console.log($rootScope.currentNavTab.name + ' tab is valid; scope.invalidTabs =' + scope.$parent.invalidTabs);
                            };
                        };
                    }
                )
            },
        };
    };

})()
The template for the directive:
<div class="tabbable">
    <ul class="nav nav-pills nav-stacked">
        <li ng-repeat="pane in panes" ng-class="{active:pane.isActive,'invalid-tab':!pane.isValid}" 
        ng-show="pane.isVisible">
            <a href="" ng-click="select(pane)" >{{pane.title}}</a>
        </li>
    </ul>
    <div class="tab-content" ng-transclude></div>
</div>
Several forms already use that smNavTabs directive. Here is one of the most complex of them:
 <div class="col-lg-2 col-md-2 panel-container ng-cloak">
                                <sm-nav-tabs name="guestTabs" id="guestTabs">
                                    <sm-nav-tab name="{{selections.mode}}.general" 
                                                title="@Labels.general" 
                                               
                                                on-activating="setShowings('general')"></sm-nav-tab>
                                    <sm-nav-tab name="edit.guestPasses" title="@Labels.passes" data-is:visible="!isNew"
                                               
                                                on-activating="setShowings('guestPasses')"></sm-nav-tab>
                                    <sm-nav-tab name="edit.invoicesList" title="@Labels.invoices" data-is:visible="!isNew"
                                                
                                                on-activating="setShowings('invoices')"></sm-nav-tab>
                                    <sm-nav-tab name="edit.guestActivity" title="@Labels.history" data-is:visible="!isNew"
                                                on-activating="setShowings('guestActivity')"></sm-nav-tab>
                                    <sm-nav-tab name="{{selections.mode}}.userDefined1" 
                                               
                                                title="@Labels.userDefined 1" on-activating="setShowings('userDefined1')"></sm-nav-tab>
                                    <sm-nav-tab name="{{selections.mode}}.userDefined2" 
                                               
                                                title="@Labels.userDefined 2" on-activating="setShowings('userDefined2')"></sm-nav-tab>
                                    <sm-nav-tab name="{{selections.mode}}.notifications" 
                                               
                                                title="@Labels.notifications" on-activating="setShowings('notifications')"></sm-nav-tab>
                                    <sm-nav-tab name="{{selections.mode}}.notes" 
                                               
                                                title="@Labels.notes" on-activating="setShowings('notes')"></sm-nav-tab>
                                    <sm-nav-tab name="{{selections.mode}}.security" 
                                               
                                                title="@Labels.security" on-activating="setShowings('security')"></sm-nav-tab>
                                    <sm-nav-tab name="{{selections.mode}}.web" 
                                               
                                                title="@Labels.web" on-activating="setShowings('web')"></sm-nav-tab>
                                </sm-nav-tabs>
                            </div>

                            <div class="col-lg-8 col-md-8 panel-container">
                                <div data-ui-view data-autoscroll="false"></div>
                                <div data-ui-view="guestPasses" ng-show="selections.showPassesView"></div>
                                <div data-ui-view="invoices" data-autoscroll="false" ng-show="selections.showInvoicesView"></div>
                            </div>
So, if I'll take your idea (which I like), I would have to get rid of the second directive and define tabs for the forms in the controller and pass to the first directive (smNavTabs). Doesn't sound like too much work, but still a bit of work. So, if the original directives can be fixed in easier way, it would be better.
If it's not broken, fix it until it is.


My Blog
Previous
Reply
Map
View

Click here to load this message in the networking platform