Dynamically set the value of ui-sref Angularjs

前端 未结 12 1825
囚心锁ツ
囚心锁ツ 2020-11-28 04:15

I have searched for a similar question but the ones that came up seem slightly different. I am trying to change the ui-sref=\'\' of a link dynamically (this link points to t

12条回答
  •  没有蜡笔的小新
    2020-11-28 05:03

    After trying various solutions I found the problem in the angular.ui.router code.

    The problem comes from the fact that ui.router update method is triggered with the ref.state which means that it is not possible to update the value of the href used when the element is clicked.

    Here are 2 solutions to solve the problem:

    Custom Directive

        module.directive('dynamicSref', function () {
        return {
            restrict: 'A',
            scope: {
                state: '@dynamicSref',
                params: '=?dynamicSrefParams'
            },
            link: function ($scope, $element) {
                var updateHref = function () {
                    if ($scope.state) {
                        var href = $rootScope.$state.href($scope.state, $scope.params);
                        $element.attr('href', href);
                    }
                };
    
                $scope.$watch('state', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        updateHref();
                    }
                });
    
                $scope.$watch('params', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        updateHref();
                    }
                });
    
                updateHref();
            }
        };
    });
    

    The HTML to use it is quite simple :

    
        Link
    
    

    Fix ui.router code :

    In angular.router.js your will find the directive $StateRefDirective (line 4238 for version 0.3).

    Change the directive code to :

    function $StateRefDirective($state, $timeout) {
        return {
            restrict: 'A',
            require: ['?^uiSrefActive', '?^uiSrefActiveEq'],
            link: function (scope, element, attrs, uiSrefActive) {
                var ref = parseStateRef(attrs.uiSref, $state.current.name);
                var def = { state: ref.state, href: null, params: null };
                var type = getTypeInfo(element);
                var active = uiSrefActive[1] || uiSrefActive[0];
                var unlinkInfoFn = null;
                var hookFn;
    
                def.options = extend(defaultOpts(element, $state), attrs.uiSrefOpts ? scope.$eval(attrs.uiSrefOpts) : {});
    
                var update = function (val) {
                    if (val) def.params = angular.copy(val);
                    def.href = $state.href(ref.state, def.params, def.options);
    
                    if (unlinkInfoFn) unlinkInfoFn();
                    if (active) unlinkInfoFn = active.$$addStateInfo(ref.state, def.params);
                    if (def.href !== null) attrs.$set(type.attr, def.href);
                };
    
                if (ref.paramExpr) {
                    scope.$watch(ref.paramExpr, function (val) { if (val !== def.params) update(val); }, true);
                    def.params = angular.copy(scope.$eval(ref.paramExpr));
                }
    
                // START CUSTOM CODE : Ability to have a 2 way binding on ui-sref directive
                if (typeof attrs.uiSrefDynamic !== "undefined") {
                    attrs.$observe('uiSref', function (val) {
                        update(val);
    
                        if (val) {
                            var state = val.split('(')[0];
                            def.state = state;
    
                            $(element).attr('href', $state.href(def.state, def.params, def.options));
                        }
                    });
                }
                // END OF CUSTOM CODE
    
                update();
    
                if (!type.clickable) return;
                hookFn = clickHook(element, $state, $timeout, type, function () { return def; });
                element.bind("click", hookFn);
                scope.$on('$destroy', function () {
                    element.unbind("click", hookFn);
                });
            }
        };
    }
    

提交回复
热议问题