web-dev-qa-db-de.com

Legen Sie den Wert von ui-sref Angularjs dynamisch fest

Ich habe nach einer ähnlichen Frage gesucht, aber die Fragen, die aufkamen, scheinen etwas anders zu sein ... Ich versuche, die ui-sref = '' eines Links dynamisch zu ändern (dieser Link zeigt auf den nächsten Abschnitt eines Assistentenformulars und das Der nächste Abschnitt hängt von der Auswahl in der Dropdown-Liste ab). Ich versuche einfach, das ui-sref-Attribut abhängig von einer Auswahl in einem Auswahlfeld zu setzen. Ich kann die ui-sref ändern, indem ich mich an ein Bereichsattribut binde, das gesetzt wird, wenn eine Auswahl getroffen wird. aber der link funktioniert nicht, ist das überhaupt möglich? Vielen Dank

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

und dann in meinem Controller setze ich den URL-Parameter auf diese Weise 

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

Alternativ dazu habe ich Direktiven verwendet, um es zum Laufen zu bringen, indem ich den Hyperlink mit dem gewünschten ui-sref-Attribut entsprechend der im Auswahlfeld ausgewählten Option generierte (Dropdown).

Dies bedeutet jedoch, dass ich den Link jedes Mal neu erstellen muss, wenn eine andere Option aus der Auswahlbox ausgewählt wird, die einen unerwünschten Flackereffekt verursacht. Meine Frage ist, ist es möglich, den Wert der ui-sref zu ändern, wie ich es oben versucht habe, indem Sie den Wert von url in meinem Controller vereinfachen, oder muss ich das gesamte Element mit jeweils einer Direktive neu erstellen Mal wird eine Auswahl getroffen, wie ich es unten gemacht habe? (zeigt dies nur der Vollständigkeit halber)

Optionsdirektive auswählen (diese Direktive generiert die Link-Direktive)

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

Hyperlink-Direktive

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

})

Hyperlink-Vorlage

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

Sieht so aus, als wäre dies möglich.

Ein Breadcrumb auf GitHub von einem der UI-Router-Autoren führte mich zu folgenden Versuchen:

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

Dann in Ihrem Controller:

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

Es stellt sich heraus, dass dies wie ein Zauber wirkt, der die Werte des Bereichs und alle ändert. Sie können sogar die Konstantenreferenz 'state-name' zu einem Bereichswert machen, wodurch auch die href in der Ansicht aktualisiert wird.

65
RavenHursT

Es gibt einen funktionierenden Plunker . Der einfachste Weg scheint die Kombination der folgenden zu sein:

  • $state.href() _ ​​(doc here ) und 
  • ng-href _ ​​(doc here )

Diese zusammen könnten verwendet werden als:

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

(Folgt dieser Plunker ) hat folgende Zustände:

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

Wir können diese Werte ändern, um href dynamisch zu generieren.

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

Überprüfen Sie es in Aktion hier

ORIGINAL:

Es gibt ein funktionierendes Beispiel wie man erreicht, was wir brauchen. Nicht jedoch mit dynamischem ui-sref.

Wie wir hier überprüfen können: https://github.com/angular-ui/ui-router/issues/395

F: [A] re dynamische UI-SREF-Attribute werden nicht unterstützt?
A: Richtig.

Aber wir können andere Funktionen von ui-router verwenden: [$state.go("statename")][5]

Das könnte also der Controller sein:

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

Und hier ist die HTML-Vorlage:

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

Das Arbeits Beispiel

HINWEIS: Es gibt mehr aktuell Link zu $ state.go definition, aber die veraltete ist mir etwas klarer

61
Radim Köhler

Werfen Sie einen Blick in diese Ausgabe # 2944 .

Der ui-sref überwacht den Statusausdruck nicht, Sie können ui-state und ui-state-params verwenden, indem Sie die Variable übergeben.

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

Auch eine schnell Demo im Ticket vorgesehen.

21
Fabio Picheli

Ich habe es auf diese Weise implementiert (ich verwende jedoch die controllerAs-Variante - nicht über $ scope).

Vorlage

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

Controller

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

Lesen Sie auch die Dokumentation zu ui-sref, wo Sie Parameter übergeben können:

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

2
codepushr

Nachdem ich verschiedene Lösungen ausprobiert hatte, fand ich das Problem im angular.ui.router-Code.

Das Problem rührt von der Tatsache her, dass die ui.router update-Methode mit dem ref.state ausgelöst wird, was bedeutet, dass der Wert der href nicht aktualisiert werden kann, wenn das Element angeklickt wird.

Hier sind 2 Lösungen, um das Problem zu lösen:

Zollrichtlinie

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

Das zu verwendende HTML ist recht einfach: 

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

Fixiere den ui.router code:

In angle.router.js finden Sie die Direktive $StateRefDirective (Zeile 4238 für Version 0.3).

Ändern Sie den Direktionscode in:

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

Am besten verwenden Sie uiRouter's $state.go('stateName', {params}) in der ng-click-Direktive der Schaltfläche. Deaktivieren Sie die Schaltfläche, wenn keine Option ausgewählt ist.

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>

Controller

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

Zustand

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

Kam, um das für immer zu beantworten :)

Glücklicherweise müssen Sie keine Schaltfläche für ng-click oder eine Funktion innerhalb einer ng-href verwenden, um das zu erreichen, was Sie suchen. Stattdessen;

Sie können eine $scope var in Ihrem Controller erstellen und die ui-sref-Zeichenfolge darin zuweisen und in Ihrer Ansicht als ui-sref-Attribut verwenden.

So was:

// 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>

Das funktioniert perfekt für mich.

1
ilter

das funktioniert nur für mich

im Controller

$scope.createState = 'stateName';

im Hinblick auf

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>

Wenn nur die $ stateParams von ui-sref in Angularjs ..__ dynamisch gesetzt werden soll. Hinweis: In inspect element wird es trotzdem als "buy ({myPairIndex: $ index})" angezeigt $ index wird in diesem Status abgerufen.

0
Ryan Augustine

Für das Verwalten von mehrere dynamische Parameter mithilfe von ui-sref meine Lösung

Html: ('MyPage.html')

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

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

Genießen !

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

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

}

Es wird ein Objekt zurückgegeben

0
bklups