ui-sref Angularjs의 값을 동적으로 설정


79

비슷한 질문을 검색했지만 나온 질문이 약간 달라 보입니다. 링크의 ui-sref = ''를 동적으로 변경하려고합니다 (이 링크는 마법사 양식의 다음 섹션을 가리키고 다음 섹션은 드롭 다운 목록에서 선택한 항목에 따라 다릅니다). 선택 상자의 일부 선택에 따라 ui-sref 속성을 설정하려고합니다. 선택이 이루어질 때 설정되는 범위 속성에 바인딩하여 ui-sref를 변경할 수 있습니다. 그러나 링크가 작동하지 않습니다. 이것이 가능합니까? 감사

  <a ui-sref="form.{{url}}" >Next Section</a>

그런 다음 컨트롤러에서 url 매개 변수를 이렇게 설정했습니다.

switch (option) {
  case 'A': {
    $scope.url = 'sectionA';
  } break;
  case 'B': {
    $scope.url = 'sectionB';
  } break;
}

또는 선택 상자 (드롭 다운)에서 선택한 옵션에 따라 원하는 ui-sref 속성으로 하이퍼 링크를 생성하여 작동하도록 지시문을 사용했습니다.

그러나 이것은 바람직하지 않은 깜박임 효과를 일으키는 선택 상자에서 다른 옵션을 선택할 때마다 링크를 다시 만들어야 함을 의미합니다. 내 질문은 이것이다, 컨트롤러에서 url의 값을 변경하는 것을 단순화하여 위에서 시도한 것처럼 ui-sref의 값을 변경할 수 있습니까 아니면 선택 할 때마다 지시문을 사용하여 전체 요소를 다시 만들어야합니까 내가 아래에서 한 것처럼 만들어 졌습니까? (완벽 함을 위해 이것을 보여주는 것)

Select 옵션 지시문 (이 지시문은 링크 지시문을 생성 함)

define(['app/js/modules/app', 'app/js/directives/hyperLink'], function (app) {
app.directive('selectUsage', function ($compile) {

    function createLink(scope,element) {
        var newElm = angular.element('<hyper-link></hyper-link>');
        var el = $(element).find('.navLink');
        $(el).html(newElm);
        $compile(newElm)(scope);
    }

    return {

        restrict: 'E',
        templateUrl: '/Client/app/templates/directives/select.html'

        ,link: function (scope, element, attrs) {

            createLink(scope, element);

            element.on('change', function () {
                createLink(scope,element);
            })
        }
    }
})

하이퍼 링크 지시문

define(['app/js/modules/app'], function (app) {
app.directive('hyperLink', function () {

    return {
        restrict: 'E',
        templateUrl: '/Client/app/templates/directives/hyperLink.html',
        link: function (scope, element, attrs) { }
    }

})

하이퍼 링크 템플릿

<div>
    <button ui-sref="form.{url}}">Next Section</button>
</div>

답변:


68

결국 이것이 가능한 것 같습니다.

ui-router 작성자 중 한 사람이 GitHub 에 대한 탐색 경로를 통해 다음을 시도했습니다.

<a ng-href="{{getLinkUrl()}}">Dynamic Link</a>

그런 다음 컨트롤러에서 :

$scope.getLinkUrl = function(){
  return $state.href('state-name', {someParam: $scope.someValue});
};

결과적으로 이것은 범위 값을 변경하는 매력처럼 작동합니다. 'state-name'문자열 상수 참조를 범위 값으로 만들 수도 있으며 뷰에서도 href를 업데이트합니다 :-)


1
가장 깨끗한 솔루션-그리고 언급 할 가치가있는 것은 "라우터 라이브러리 독립적"입니다.
Radek Anuszewski

1
이렇게하면 getLinkUrl ()이 모든 다이제스트주기 (매우 자주)가 처리됩니다. getLinkUrl ()에 console.log를 붙이고 페이지에서 마우스를 움직이면 로그가 날아가는 것을 볼 수 있습니다. 이 방법이 작동하지 않는다는 말이 아니라 그냥 지저분합니다.
Suamere

2
이것은 3 년 전에 Angular 1.4로 작성된 솔루션입니다. 당시 Angular 버전으로 원하는 기능을 달성 할 수있는 유일한 옵션이었습니다. 비판하고 대답에 반대표를 던지는 것, 대안적인 해결책을 제시하지 않고 (만약 있다면) 아무에게도 도움이되지 않습니다.
RavenHursT

1
그것은 절대적 않습니다 도움을. 미래의 시청자에게 이것이 최선의 해결책이 아닐 수 있으며 다른 곳에서보아야한다고 제안합니다. 그 코멘트에 대해 "비구 성적"은 없었습니다. 구조적이지 않은 것이 있다면 사용자에게 유효한 비판을 비판하는 응답이었습니다 (그리고 반대표가 댓글에 연결된 것처럼 증거에없는 사실을 가정).
Cody Gray

1
@FabioPicheli의 답변은 더 업데이트 된 기본 솔루션을 제공하므로 확인하십시오.
phazei

61

작업 plunker은 . 가장 쉬운 방법은 다음 조합을 사용하는 것 같습니다.

  • $state.href() ( 여기 문서 )
  • ng-href ( 여기 문서 )

이들은 함께 다음과 같이 사용할 수 있습니다.

<a ng-href="{{$state.href(myStateName, myParams)}}">

따라서 ( 이 plunker 다음에 이어 ) 다음과 같은 상태를 갖습니다 .

$stateProvider
  .state('home', {
      url: "/home",
      ...
  })
  .state('parent', {
      url: "/parent?param",
      ...
  })
  .state('parent.child', { 
      url: "/child",
      ...

이러한 값을 변경하여 href 를 동적으로 생성 할 수 있습니다.

<input ng-model="myStateName" />
<input ng-model="myParams.param" />

체크인 여기 실제로 하십시오.

실물:

우리가 필요한 것을 달성하는 방법에 대한 실제적인 예가 있습니다. 그러나 동적으로ui-sref .

여기에서 확인할 수 있습니다. https://github.com/angular-ui/ui-router/issues/395

Q : [A] 동적 ui-sref 속성이 지원되지 않습니까?
A : 맞습니다.

그러나 우리는 다른 기능을 사용할 수 있습니다 ui-router .[$state.go("statename")][5]

그래서 이것은 컨트롤러 물건이 될 수 있습니다.

$scope.items = [
  {label : 'first', url: 'first'},
  {label : 'second', url: 'second'},
  {label : 'third', url: 'third'},
];
$scope.selected = $scope.items[0];
$scope.gotoSelected = function(){
  $state.go("form." + $scope.selected.url);
};

다음은 HTML 템플릿입니다.

<div>
  choose the url:
  <select
    ng-model="selected"
    ng-options="item.label for item in items"
  ></select>

  <pre>{{selected | json}}</pre>
  <br />
  go to selected
  <button ng-click="gotoSelected()">here</button>

  <hr />
  <div ui-view=""></div>
</div>

작업

참고 : $ state.go 정의에 대한 최신 링크 가 더 있지만 더 이상 사용되지 않는 링크가 더 명확합니다.


1
IMHO, 이것은 원하는 동작을 완전히 수행하지 않습니다. ui-sref는 실제로 ui-sref 지시문을 초기화 할 때 앵커 태그의 href 속성을 설정합니다. 동적으로 제어되는 앵커 태그에 대해 일반적으로 수행하는 작업은 다음과 같습니다. <a ui-sref="{{scopedStateName}}( { 'some-state-param': '{{scopedParamValue}}' })">My Dynamic Link</a> 이 접근 방식의 유일한 문제는 분명히 ui-sref가 범위 변수의 변경 사항을 감시하지 않기 때문에 href가 후속 값 변경시 변경되지 않는다는 것입니다. . AFAIK, ui-sref는 이것을 지원하지 않습니다.
RavenHursT 2015 년

조금 더 연구 한 끝에 상태 매개 변수가있는 상태를 참조하는 동적으로 생성 된 href 속성을 수행하는 방법을 찾은 것 같습니다. 아래 내 대답을 참조하십시오.
RavenHursT 2015 년

ng-href를 사용하는 동안 하드 페이지 새로 고침을 어떻게 피하고 있습니까? ng-href가 ui-routers $state.go()메서드를 사용하지 않기 때문에 현재이 솔루션에 문제가 있습니다.
Andre는

27

이번 호 2944 호를 살펴보십시오 .

ui-sref상태 식을 보지 않는, 당신은 사용할 수 ui-stateui-state-params변수를 전달합니다.

  <a data-ui-state="selectedState.state" data-ui-state-params="{'myParam':aMyParam}">
       Link to page {{selectedState.name}} with myParam = {{aMyParam}}
  </a>

또한 티켓에서 제공 되는 빠른 데모 .


1
큰. 그것은 UI-SREF 활성뿐만 아니라 부가적인 논리와 지원을 필요로하지 않습니다
Julia

2

나는 이것을 이런 방식으로 구현할 수 있었다 ($ scope를 통하지 않고 controllerAs 변형을 사용하고있다).

주형

<button ui-sref="main({ i18n: '{{ ctrlAs.locale }}' })">Home</button>

제어 장치

var vm = this;
vm.locale = 'en'; // or whatever dynamic value you prepare

또한 문서를 참조하십시오. ui-sref 매개 변수를 전달할 수 .

https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref


아니요, button와 동일한 방식으로 작동합니다 a. 지시문은 실제로 href컴파일 타임에 버튼에 속성을 생성 하지만 업데이트하지 않습니다. 그리고 버튼을 클릭하면 항상 href값의 상태로 이동 하지만 업데이트되지는 않습니다ui-sref
Jens

2

다양한 솔루션을 시도한 후 angular.ui.router코드 에서 문제를 발견했습니다 .

문제는 ui.router update메서드가으로 트리거 된다는 사실에서 비롯 됩니다. 이는 요소를 클릭 할 때 사용 된 ref.state의 값을 업데이트 할 수 없음을 의미합니다 href.

문제를 해결하기위한 두 가지 해결책은 다음과 같습니다.

사용자 지정 지시문

    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();
        }
    };
});

사용하는 HTML은 매우 간단합니다.

<a  dynamic-sref="home.mystate"
    dynamic-sref-params="{ param1 : scopeParam }">
    Link
</a>

ui.router 코드 수정 :

angular.router.js에서 지시문을 찾을 수 있습니다. $StateRefDirective (버전 0.3의 경우 4238 행).

지시문 코드를 다음으로 변경하십시오.

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);
            });
        }
    };
}

2
당신이 자신의 포크를 만들지 않는 한 angular-ui-router나는 그것에 대해 제안 할 것입니다. 동료 동료가 업데이트를 시도하고 붐을 일으켜 버그가 어디에서 왔는지 아무도 모릅니다.
Rafael Herscovici

1

그것에 대해 좋은 대답을 했어요 :)

다행스럽게도 ng-click 버튼을 사용하거나 원하는 것을 얻기 위해 ng-href 내부의 함수 를 사용할 필요가 없습니다 . 대신;

$scope컨트롤러에서 var를 만들고 여기에 ui-sref문자열을 할당하고 뷰에서 사용할 수 있습니다.ui-sref 속성 .

이렇게 :

// Controller.js

// if you have nasted states, change the index [0] as needed.
// I'm getting the first level state after the root by index [0].
// You can get the child by index [1], and grandchild by [2]
// (if the current state is a child or grandchild, of course).
var page = $state.current.name.split('.')[0];
$scope.goToAddState = page + ".add";


// View.html
<a ui-sref="{{goToAddState}}">Add Button</a>

그것은 나를 위해 완벽하게 작동합니다.


1
나는 당신의 접근 방식을 시도, 내가 볼 수 ui-sref있지만 hrefgenerated.Any 제안을하지
Arepalli Praveenkumar

나는 내 대답에 "href"를 언급하지 않았다. 그게 어떤 관련이 있습니까?
ilter

1
ui-sref는 제공된 상태에 url이있는 경우 요소에 href 속성을 설정하는 지시문입니다 (이 경우에는 분명하지 않음).
askmike 2015-09-21

2
@ilter 이것은 처음으로 작동하지만 양방향 바인딩이 없습니다. 범위가 변경 될 때 링크가 업데이트되지 않습니다.
Ben

1
나는 나 자신을 위해서만 말할 수 있지만, 제 경우에는 대답이 질문에 맞지 않기 때문입니다. 드롭 다운이 변경되면 더 이상 유효한 링크가 없습니다.
Josh Gagnon

1

가장 좋은 방법은 uiRouter's $state.go('stateName', {params})버튼의ng-click 지시문 . 옵션을 선택하지 않으면 버튼을 비활성화하십시오.

HTML

<select ng-model="selected" ng-options="option as option.text for option in options"></select>
<button ng-disabled="!selected" type="button" ng-click="ctrl.next()">Next</button>

제어 장치

function Controller($scope, $state){
    this.options = [{
        text: 'Option One',
        state: 'app.one',
        params: {
            param1: 'a',
            param2: 'b'
        }
    },{
        text: 'Option Two',
        state: 'app.two',
        params: {
            param1: 'c',
            param2: 'd'
        }
    },{
        text: 'Option Three',
        state: 'app.three',
        params: {
            param1: 'e',
            param2: 'f'
        }
    }];

    this.next = function(){
        if(scope.selected){
            $state.go($scope.selected.state, $scope.selected.params || {});
        }
    };
}

상태

$stateProvider.state('wizard', {
    url: '/wizard/:param1/:param2', // or '/wizard?param1&param2'
    templateUrl: 'wizard.html',
    controller: 'Controller as ctrl'
});

1
UI-(SREF) - 활성 또는 UI-(SREF) - 액티브 EQ이 작동하지 않음
KFE

1
<a ng-click="{{getLinkUrl({someParam: someValue})}}">Dynamic Link</a>

$scope.getLinkUrl = function(value){
  $state.go('My.State',{someParam:value});

}

객체를 반환합니다.


0

이것은 나를 위해 일하고 있습니다

컨트롤러에서

$scope.createState = 'stateName';

보기에

ui-sref="{{ createState }}"

4
@ben이 다른 답변에 언급했듯이 : 이것은 처음으로 작동하지만 양방향 바인딩이 없습니다. 범위가 변경 될 때 링크가 업데이트되지 않습니다
Jens

0

ui-sref를 사용하여 여러 동적 매개 변수 를 관리 하려면 여기 내 솔루션이 있습니다.

HTML : ( 'MyPage.html')

<button type="button" ui-sref="myState(configParams())">

컨트롤러 : ( 'MyCtrl')

.controller('MyCtrl', function ($scope) {
  $scope.params = {};
  $scope.configParams = function() {
    $scope.params.param1 = 'something';
    $scope.params.param2 = 'oh again?';
    $scope.params.param3 = 'yes more and more!';
    //etc ...

    return $scope.params;
  };
}

stateProvider : ( 'myState')

 $stateProvider
          .state('myState', {
            url: '/name/subname?param1&param2&param3',
            templateUrl: 'MyPage.html',
            controller: 'MyCtrl'
          });

즐겨 !


그것은 현재 상태에서 나에게 myState하지 탐색이 할 수있는 내용의 오류를 제공합니다
마니

@Mani ui-router 를 사용하고 있습니까? 코드를 볼 수 있습니까?
Emidomenge

예, ui-router를 사용하고 있습니다. <ion-item class = "accordion-item"ng-repeat = "item in group.items"ng-show = "isGroupShown (group)"ui-sref = "{{item.state}}"ui-sref-active = "iactive"> {{item.title}} </ ion-item>
Mani

시도 ui-sref="item.state"
Emidomenge

꽃 교정기로만 작동합니다. 죄송 해요. 내가 실수 한 다른 곳이 있었다. 죄송합니다.
Mani

0
<ul class="dropdown-menu">
  <li ng-repeat="myPair in vm.Pairs track by $index">
     <a ui-sref="buy({myPairIndex:$index})"> 
          <span class="hidden-sm">{{myPair.pair}}</span>
     </a>
  </li>
</ul>

누군가 Angularjs 에서 ui-sref$ stateParams 를 동적으로 설정하려는 경우 . 참고 : inspect 요소에서는 여전히 "buy ({myPairIndex : $ index})"로 표시되지만 $ index는 해당 상태에서 가져옵니다.


-1

또는 다음과 같이 :

<a ui-sref="{{ condition ? 'stateA' : 'stateB'}}">
  Link
</a>

3
다른 답변에서 @ben이 언급했듯이 : 이것은 처음으로 작동하지만 양방향 바인딩이 없습니다. 범위가 변경 될 때 링크가 업데이트되지 않습니다
Jens

나는이 방법을 시도하고 있지만 어떤 제안도 할 수 없었다
Aswin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.