2015-02-18 22 views
7

Ho una pagina HTML, una volta caricata nel browser dell'utente lo stato 'elenco' è attivato e il partial 'list' è tirato da Angular e popolato con un elenco di server.Angular-UI-Router: ui-sref non sta creando href con i parametri

Ogni server ha un collegamento "dettagli" che specifica lo stato "dettagli" per quel server.

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

Quando reso l' 'ui-sref' genera l'URL previsto 'href' sulla base del percorso e dei suoi parametri opzionali.

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

Quando cliccato funziona come previsto e 'dettagli' parziali è tirato e nel controller assegnato a quello stato tira il server con il nome specificato.

Il problema che sto incontrando è il fatto che una volta caricato il partial 'details', anch'esso ha uno 'ui-sref' in uno stato 'edit'.

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

Ma quando questo parziale viene caricato l'URL 'ui-sref' non sta generando la corretta 'href'.

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

Come si può vedere l'url 'href' è '#/modificare /' non '#/modificare/SLCMedia' come ci si aspetterebbe. Deve essere qualcosa di semplice che mi manca. Il cambiamento di stato ha qualcosa a che fare con esso?

Qui ci sono tutti gli "stati" definiti per la pagina.

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

Qui sono i miei controllori

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

risposta

19

Hmm, probabilmente sto equivoco il problema ma vedo almeno una differenza evidente tra l'aspetto del codice e l'aspetto della mia.

miei links angolare-ui-router simile a questa:

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

La differenza è l'assenza di parentesi graffe intorno rep.id. Quindi mi chiedo se la modifica di questa

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

a questo

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

potrebbe fare qualcosa per te.

Probabilmente no, ma è la prima cosa che mi è venuta in mente.

+1

Bene, la rimozione delle parentesi graffe {{}} ha funzionato! In modo che sollevi la domanda, perché funziona con le parentesi sulla lista parziale ma non sui dettagli parziali? Che trovo un comportamento completamente strano. E solo per notare, funziona ancora sulla lista parziale se rimuovo anche il {{}}. – Schleichermann

+1

Penso che abbia a che fare con la ng-repeat che si assicura per prima cosa: le espressioni vengono valutate, quindi: l'ui-sref dà il via alla sua magia. – Highmastdon

0

Ho creato simplified, but working version here. Perché non c'è niente, ovviamente, sbagliato. Questo esempio dovrebbe almeno aiutarti a garantire che:

Tutto quello che stai cercando di fare dovrebbe funzionare.

Qui sono stati:

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

Ecco controllore di un elenco di dati di carico

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

(server.json) - esempio di dati

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

e lo stesso modello:

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

Tutto funziona come previsto. Controllalo here.

0

Voglio contribuire con un altro datapoint nel caso in cui altre persone arrivino qui con una domanda simile, come ho fatto io.

Nella mia app stavo usando la versione non ricciuta e non funzionava. Le mie specifiche riguardano InfoWindow in Google Maps. Credo che ci sia un "problema" di ordine di rendering tale che i dati richiesti per il collegamento ui-sref non esistano, e quando finalmente esiste, non viene mai "ri-reso".

(non funzionante) Versione originale:

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

versione di lavoro:

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

ho messo il tag %pre con le informazioni per dimostrare a me stesso che il dato era in -fatto presente (almeno alla fine/alla fine), ma anche se il codice originale per il collegamento non funzionava. Ho adattato il mio codice per utilizzare la versione interpolata di parentesi graffa come per la situazione degli OP e ha funzionato.

Conclusione: La soluzione potrebbe dipendere dal modo in cui il componente padre gestisce il rendering. Google Maps in questo caso è abbastanza noto per essere "funky" (termine tecnico) con rendering, in particolare in Angu-land.

Problemi correlati