web-dev-qa-db-ja.com

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属性を持つハイパーリンクを生成することで機能させるようにしました。

しかし、これは、selectboxから異なるオプションを選択するたびにリンクを再作成する必要があることを意味し、望ましくないちらつき効果を引き起こします。私の質問はこれです、コントローラでurlの値を変更することで上記を試してみたときにui-srefの値を変更することは可能ですか、または選択するたびにディレクティブを使用して要素全体を再作成する必要がありますか以下のように作られていますか? (完全を期すためにこれを表示するだけです)

オプションディレクティブの選択(このディレクティブはリンクディレクティブを生成します)

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>
77
user3728830

結局これができるように見えます。

Ui-routerの作成者の1人による GitHub のブレッドクラムにより、次のことを試すようになりました。

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

次に、コントローラーで:

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

結局のところ、これはスコープ値とすべてを変更するチャームのように機能します。 'state-name'文字列定数にスコープ値を参照させることもできます。これにより、ビューのhrefも更新されます:-)

66
RavenHursT

動作しているプラ​​ンカー があります。最も簡単な方法は、次の組み合わせを使用することです。

  • $state.href()(doc hereおよび
  • ng-href(doc here

これらは一緒に使用できます:

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

したがって、(following this 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" />

ここでのアクション で確認してください

元の:

実例があります how to 必要なものを実現します。しかし、動的な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 定義へのリンクがありますが、非推奨のものはもう少し明確です

61
Radim Köhler

この問題をご覧ください #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>

また、すぐに デモ チケットで提供されます。

25
Fabio Picheli

私はこの方法でなんとか実装しました($ 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

2
codepushr

さまざまな解決策を試した後、angular.ui.routerコードで問題を見つけました。

問題は、ui.router updateメソッドがref.stateでトリガーされるという事実に由来します。これは、エレメントがクリックされたときに使用されるhrefの値を更新できないことを意味します。

問題を解決するための2つの解決策を次に示します。

カスタムディレクティブ

    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
Linvi

最適なアプローチは、ボタンのng-clickディレクティブでuiRouter's $state.go('stateName', {params})を使用することです。オプションが選択されていない場合は、ボタンを無効にします。

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
rynangeles

良いことにそれを答えに来ました:)

幸いなことに、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
ilter

これはちょうど私のために働いています

コントローラー内

$scope.createState = 'stateName';

ビューで

ui-sref="{{ createState }}"
0
Abou-Emish
<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で$ stateParamsi-srefのみを動的に設定したい場合。注:検査要素では、「buy({myPairIndex:$ index})」として表示されますが、その状態では$ indexが取得されます。

0
Ryan Augustine

複数の動的パラメーター 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'
          });

楽しい !

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

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

}

オブジェクトを返します

0
bklups