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

비슷한 질문을 검색했지만 나온 질문이 약간 달라 보입니다. 링크의 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>



답변

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

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

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

그런 다음 컨트롤러에서 :

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

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


답변

작업 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 정의에 대한 최신 링크 가 더 있지만 더 이상 사용되지 않는 링크가 더 명확합니다.


답변

이번 호 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>

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


답변

나는 이것을 이런 방식으로 구현할 수 있었다 ($ 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


답변

다양한 솔루션을 시도한 후 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);
            });
        }
    };
}


답변

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

다행스럽게도 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>

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


답변

가장 좋은 방법은 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'
});