2015-02-18 10 views
7

Mam stronę HTML, po załadowaniu do przeglądarki użytkownika aktywowany jest stan "list", a część "list" jest ciągnięta przez Angular i wypełniona lista serwerów.Angular-UI-Router: ui-sref nie buduje href z parametrami

Każdy serwer ma link "szczegóły", który określa stan "szczegóły" dla tego serwera.

<td><a ui-sref="details({ serverName: '{{server.name}}' })">Details</a></td> 

Po wyrenderowaniu "ui-sref" generuje oczekiwany URL "href" na podstawie trasy i jej opcjonalnych parametrów.

<a ui-sref="details({ serverName: 'SLCMedia' })" href="#/details/SLCMedia">Details</a> 

Po kliknięciu działa zgodnie z oczekiwaniami i wyciągnął „szczegóły” częściowe iw sterowniku przypisanego do tego stanu ciągnie serwer o nazwie podanej.

Problem, który napotykam, to fakt, że po załadowaniu częściowej "szczegóły", ma ona również "ui-sref" do stanu "edycji".

<a ui-sref="edit({ serverName: '{{server.name}}' })"> 
     <button class="btn btn-lg btn-labeled btn-primary"> 
      <span class="btn-label icon fa fa-edit"></span> 
      Edit 
     </button> 
    </a> 

Ale kiedy ten jest częściowym załadowaniu 'UI-sref' nie generuje poprawny 'href' url.

<a ui-sref="edit({ serverName: 'SLCMedia' })" href="#/edit/"> 
     <button class="btn btn-lg btn-labeled btn-primary"> 
      <span class="btn-label icon fa fa-edit"></span> 
      Edit 
     </button> 
    </a> 

Jak widać 'href' url jest '#/edit /' nie '#/edit/SLCMedia', jak można by się spodziewać. To musi być coś prostego, czego mi brakuje. Czy zmiana stanu ma z tym coś wspólnego?

Oto wszystkie zdefiniowane "stany" dla strony.

// Create the Angular App to rule the Server Management Page 
var serverApp = angular.module('serverApp', [ 
    'ui.router', 
    'serverControllers', 
    'utilitiesService' 
]); 

serverApp.config(function ($stateProvider, $urlRouterProvider) { 
    // For any unmatched url, redirect to /state1 
    $urlRouterProvider.otherwise("/list"); 

    // Now set up the states 
    $stateProvider 
     .state('list', { 
      url: '/list', 
      templateUrl: '/views/pages/servers/list.html', 
      controller: 'serverListCtrl' 
     }) 
     .state('details', { 
      url: '/details/:serverName', 
      templateUrl: '/views/pages/servers/details.html', 
      controller: 'serverDetailsCtrl' 
     }) 
     .state('create', { 
      url: '/create', 
      templateUrl: '/views/pages/servers/create.html' 
     }) 
     .state('edit', { 
      url: '/edit/:serverName', 
      templateUrl: '/views/pages/servers/edit.html', 
      controller: 'serverEditCtrl' 
     }) 
}); 

Oto moje kontrolery

var serverControllers = angular.module('serverControllers', ['utilitiesService']); 

serverControllers.controller('serverListCtrl', function ($scope, $http) { 
    $http.get('/servers/getList').success(function (data) { 
     $scope.serverList = data; 
    }); 
}); 

serverControllers.controller('serverDetailsCtrl', function ($scope, $stateParams, $http) { 
    var serverName = $stateParams.serverName; 

    $http.get('/servers/getServerByName/' + serverName).success(function (data) { 
     $scope.server = data; 
    }); 
}); 

serverControllers.controller('serverEditCtrl', function ($scope, $stateParams, $http, $state, showAlertMessage) { 
    var serverName = $stateParams.serverName; 

    $http.get('/servers/getServerByName/' + serverName).success(function (data) { 
     $scope.server = data; 
    }); 

    $scope.server.submitForm = function (item, event) { 
     console.log("--> Submitting Server Update"); 

     //TIMDO: Verify all required fields have been included 

     var responsePromise = $http.post("/servers/postEdit", $scope.server, {}); 
     responsePromise.success(function(dataFromServer, status, headers, config) { 
      showAlertMessage({ 
       type: 'success', 
       title: 'Success', 
       message: 'Server information updated' 
      }); 

      $state.go('clear'); 
     }); 
     responsePromise.error(function(data, status, headers, config) { 
      showAlertMessage({ 
       type: 'error', 
       title: 'Success', 
       message: 'Server information updated' 
      }); 
     }); 
    } 
}); 

Odpowiedz

19

Hmm, ja chyba nieporozumienie problem ale widzę co najmniej jedną oczywistą różnicę pomiędzy wyglądem swojego kodu i wygląd kopalni.

Moje linki kątowe-ui-routera wyglądać następująco:

<a ui-sref="reps-show({ id: rep.id })">{{rep.name}}</a> 

Różnica polega na braku szelek całym rep.id. Więc zastanawiam się, czy zmiana tego

<td><a ui-sref="details({ serverName: '{{server.name}}' })">Details</a></td> 

do tego

<td><a ui-sref="details({ serverName: server.name })">Details</a></td> 

może zrobić coś dla ciebie.

To chyba nie to, ale to pierwsza rzecz, która przyszła mi do głowy.

+1

Cóż, usunięcie nawiasów klamrowych {{}} działało! Nasuwa się więc pytanie, dlaczego działa z nawiasami na liście częściowej, ale nie częściowej? Że znajduję całkowicie dziwne zachowanie. I wystarczy zauważyć, że nadal działa na liście częściowej, jeśli usunę również {{}}. – Schleichermann

+1

Myślę, że ma to związek z powtórzeniem ng, które zapewnia, że ​​najpierw: wyrażenia są oceniane, a następnie: ui-sref rozpoczyna swoją magię. – Highmastdon

0

Utworzono simplified, but working version here. Ponieważ nie ma oczywiście niczego złego. Ten przykład powinien pomóc Ci upewnić się, że:

Wszystko, co próbujesz zrobić, powinno działać.

Oto czytamy:

// States 
$stateProvider 
     .state('list', { 
      url: "/list", 
      templateUrl: 'tpl.list.html', 
      controller: 'serverListCtrl', 
     }) 
     .state('edit', { 
     url: '/edit/:serverName', 
     templateUrl: 'tpl.html', 
     controller: 'serverEditCtrl' 
    }) 

Oto kontroler listy ładowanie danych

.controller('serverListCtrl', ['$scope', '$http', function ($scope, $http) { 
    $http.get('server.json').success(function (data) { 
     $scope.serverList = data; 
    }); 
}]) 

(server.json) - przykład danych

[ 
    {"name":"abc"}, 
    {"name":"def"}, 
    {"name":"xyz"} 
] 

i te same szablon:

<li ng-repeat="server in serverList"> 
    <a ui-sref="edit({ serverName: '{{server.name}}' })"> 
     <button class="btn btn-lg btn-labeled btn-primary"> 
      <span class="btn-label icon fa fa-edit"></span> 
      Edit {{server.name}} 
     </button> 
    </a> 
</li> 

Wszystko działa zgodnie z oczekiwaniami. Sprawdź to here.

0

Chcę przyczynić się z innym datapoint w przypadku, gdy inni ludzie przybywają tutaj z podobnym pytaniem, tak jak ja.

Używałem w aplikacji aplikacji nie-nawiasy klamrowe, która nie działała. Moja specyfika dotyczy InfoWindow w Google Maps. Wydaje mi się, że istnieje "kwestia" zlecenia renderowania, tak że dane wymagane dla odnośnika ui-sref nie istnieją, a kiedy już istnieją, to nigdy nie są "ponownie renderowane".

Original (bez pracy) wersja:

%h3 
    {{window_info.data.user.name || "Mystery Person"}} 
%a.fa.fa-info-circle{ ui: { sref: 'users.show({id: window_info.data.user.id })' } } 
%pre {{window_info.data.user.id | json}} 

wersja robocza:

%h3 
    {{window_info.data.user.name || "Mystery Person"}} 
%a.fa.fa-info-circle{ ui: { sref: "users.show({id: '{{ window_info.data.user.id }}' })" } } 
%pre {{window_info.data.user.id | json}} 

umieściłem tag %pre z informacją, aby udowodnić sobie, że punkt odniesienia był w -fact obecny (przynajmniej ostatecznie/ostatecznie), ale nawet nadal oryginalny kod dla linku nie działa. Poprawiłem swój kod, aby użyć interpolowanej wersji nawiasów klamrowych zgodnie z sytuacją PO i zadziałało.

Wniosek: Twoje rozwiązanie może zależeć od sposobu, w jaki komponent macierzysty przetwarza renderowanie. Google Maps w tym przypadku jest dość znany jako "funky" (pojęcie techniczne) z renderowaniem, szczególnie w Angu-land.