0

The example 끈적한 상태에 대한 ui-router-extras는 $ state와 함께 ng-show를 사용하여 뷰를 표시하거나 숨길 필요가 있음을 보여줍니다. 따라서 우리는 $ state를 $ rootscope에 전역 적으로 주입하여이 예제에서 어떤 식 으로든 액세스 할 수 있도록해야합니다.

이 변수가 내 범위를 통해 전역 적으로 크롤링되고 모든 컨트롤러의 해당 변수를 로컬로 주입하는 것이 최적이라고 생각하지 않는다고 생각하지 않습니다. 어떻게 좀 더 우아하게 해결할 수 있습니까?

답변

0

나는 ui-sref directivesource code을 연구하여 비슷한 지시문을 만들 수 있는지 여부를 알아 냈지만 현재 상태에 따라 활성 클래스를 설정하는 대신 현재 요소의 가시성을 변경했습니다.

불행히도 ui-router는 그런 식으로 확장되지 않는 것처럼 보입니다. 그러나 나는 내 지시문을 함께 해킹 할 수있다. parseStateRefstateContext은 다른 코드에서 액세스 할 수없는 ui-router 소스 코드의 & 붙여 넣기 기능입니다.

소스 코드는 의도 한대로 현재 프로젝트에서 작동하지만 필자는 프로젝트에서 생각할 필요가없는 부분을 놓치게됩니다.

어쨌든 : 사용은 <... show-on-sref="targetState">이됩니다. 필자는 자식 상대 링크 (.someState과 같은 점으로 시작하는 자식 상대 링크)를 사용하여 지침을 성공적으로 테스트했습니다.

var attributeName = 'showOnSref'; 

function parseStateRef(ref, current) { 
    var preparsed = ref.match(/^\s*({[^}]*})\s*$/), parsed; 
    if (preparsed) ref = current + '(' + preparsed[1] + ')'; 
    parsed = ref.replace(/\n/g, " ").match(/^([^(]+?)\s*(\((.*)\))?$/); 
    if (!parsed || parsed.length !== 4) throw new Error("Invalid state ref '" + ref + "'"); 
    return { state: parsed[1], paramExpr: parsed[3] || null }; 
} 
function stateContext(el) { 
    var stateData = el.parent().inheritedData('$uiView'); 

    if (stateData && stateData.state && stateData.state.name) { 
     return stateData.state; 
    } 
} 

angular 
    .module('showOnSref', []) 
    .directive(attributeName, ['$state', function($state) { 
     return { 
      restrict: 'A', 
      link: function(scope, element, attrs) { 
       var ref = parseStateRef(attrs[attributeName], $state.current.name), 
        linkedState = $state.get(ref.state, stateContext(element)), 
        params = angular.copy(scope.$eval(ref.paramExpr)), 
        inactiveClass = 'ng-hide', 
        bind = angular.bind, 
        show = bind(element, element.removeClass, inactiveClass), 
        hide = bind(element, element.addClass, inactiveClass), 
        update = function() { 
         $state.includes(linkedState.name, params) ? show() : hide(); 
        }; 
        scope.$on('$stateChangeSuccess', update); 
      } 
     }; 
    }]); 
3

이것은 사용자 지정 지시문에 가장 적합한 응용 프로그램입니다.

app.directive("showWhenStateActive", function($state) { 
    return { 
     restrict: 'A', 
     link: function(scope, elem, attrs) { 
     var stateChangedFn = function stateChanged() { 
      var addOrRemoveFnName = $state.includes(attrs.showWhenStateActive) ? "removeClass" : "addClass"; 
      elem[addOrRemoveFnName]("ng-hide"); 
     }; 
     scope.$on("$stateChangeSuccess", stateChangedFn); 
     } 
    } 
    }); 

이를 사용하려면, 단지 태그에 속성으로 추가하고 확인하려는 국가 이름을 제공 : 다음은 간단한 당신이 당신의 UI 뷰 태그에 추가 할 수있는 지침이다.

예를 들어, ui-router-extras Sticky State example에, 당신은이에서 변경됩니다 :

<div class="tabcontent well-lg" ui-view="peopletab" ng-show="$state.includes('top.people')" class="col-sm-6"></div> 
<div class="tabcontent well-lg" ui-view="invtab" ng-show="$state.includes('top.inv')" class="col-sm-6"></div> 
<div class="tabcontent well-lg" ui-view="custtab" ng-show="$state.includes('top.cust')" class="col-sm-6"></div> 

이에 :

<div class="tabcontent well-lg" ui-view="peopletab" show-when-state-active="top.people" class="col-sm-6"></div> 
<div class="tabcontent well-lg" ui-view="invtab" show-when-state-active="top.inv" class="col-sm-6"></div> 
<div class="tabcontent well-lg" ui-view="custtab" show-when-state-active="top.cust" class="col-sm-6"></div>