2015-05-12 6 views
9

Il mio obiettivo è scrivere un'app SAPUI5 Fiori con supporto per il routing. Un obiettivo di posta è avere URL passabili. Ad esempio in un messaggio di posta elettronica come "approvare questo: collegamento". Il collegamento è un URL corrispondente alla mia configurazione di rounting, ad es. index.html#/applicants/8.Instradamento in SAPUI5: come implementare il passaggio dell'URL? Dati di modello non caricati inizialmente

Uso un tipico tipo di applicazione sap.m.SplitApp. Facendo clic su una voce di elenco in visualizzazione principale, l'URL viene modificato in index.html#/applicants/[id of entry in JSON]. Posso fare clic sull'elenco, le mie route definite vengono abbinate e le app caricano i dati (candidati) come previsto.

Tuttavia, e qui viene la mia domanda, questo doeas non funziona quando si utilizza un URL direttamente, ad esempio incollando [my url]/index.html#/applicants/8 nel mio browser. L'app viene avviata ma non vengono caricati dati di dettaglio. Devo fare nuovamente clic su un'altra voce di elenco per ottenere i dati.

In realtà, il controller viene chiamato quando passa l'URL, ma sembra che il modello non sia iniziato e non definito. Il mio modello JSON è legato nella funzione createContent dei miei Component.js

// Aggiornamento 2015-05-14 I problemi sembra essere intorno alla funzione getData(). Ho il modello, ha le voci, ma getData() restituisce undefined per la prima volta che viene caricata la mia app. Recentemente ho letto getData() è deprecato. Come dovrei migliorare la mia codifica qui sotto?

// Component.js 
ui5testing.Component.prototype.createContent = function(){ 
    // create root view 
    var oView = sap.ui.view({ 
    id : "app", 
    viewName : "ui5testing.view.Main", 
    type : "JS", 
    viewData : { 
     component : this 
    } 
    var oModel = new sap.ui.model.json.JSONModel("model/mock_applicants.json"); 
    oView.setModel(oModel); 
    [...] 
    return oView; 
}); 
// Master controller 
handleApplicantSelect : function (evt) { 
    var oHashChanger = sap.ui.core.routing.HashChanger.getInstance(); 
    var context = evt.getParameter("listItem").getBindingContext(); 
    var path = context.getPath(); 
    var model = this.getView().getModel(); 
    var item = model.getProperty(path); 
    oHashChanger.setHash("applicants/" + item.id); 
}, 

// Detail controller 
onInit: function() { 
    this.router = sap.ui.core.UIComponent.getRouterFor(this); 
    this.router.attachRoutePatternMatched(this._handleRouteMatched, this); 
}, 

_handleRouteMatched : function(evt){   
    var objectId = evt.getParameter("arguments").id; 
    var model = this.getView().getModel(); 
    var data = model.getData()["applicants"]; 
    var pathId; 

    if (data) { 
     for (var i = 0; data.length; i++) { 
      if (objectId == data[i].id) { 
       pathId = i; 
       break; 
      } 
     } 

     var sPath = "/applicants/" + pathId; 

     var context = new sap.ui.model.Context(model, sPath) 
     this.getView().setBindingContext(context);    
    } 
}, 
+1

è chiamato createContent? Come e dove si imposta la modella? . This.getView() getModel(); non sembra una buona idea quando il modello non è già collegato alla vista particolare PRIMA. – cschuff

+0

Scusa, l'ho già risolto. Vedi l'aggiornamento. – SDD64

+0

Scusa ancora, dopo un refactoring il problema è emerso nuovamente. Il modello è impostato in Compoent.js createContent(). Impostare sulla vista radice principale. – SDD64

risposta

4

Come hai capito che getData() restituisce definito per la prima volta, il che significa che i dati modella non è ancora ancora caricata. Pertanto, è possibile utilizzare il metodo attachRequestCompleted del modello & e attivare un evento dal componente & per ascoltare quell'evento nel controller di dettaglio per garantire che il routerPatternMatched() venga eseguito solo dopo il caricamento dei dati.

//Component.js

var oModel = new sap.ui.model.json.JSONModel("model/mock_applicants.json"); 

oModel.attachRequestCompleted(jQuery.proxy(function(){ 
    this.fireEvent("MockDataLoaded"); // fireEvent through component 
},this)); 

oView.setModel(oModel); 

// Particolare controllore

onInit : function(){ 

this.router = sap.ui.core.UIComponent.getRouterFor(this); 

var oComponent = this.getOwnerComponent(); 

oComponent.attachEvent("MockDataLoaded",jQuery.proxy(function(){ 
    this.router.attachRoutePatternMatched(this._handleRouteMatched, this); 
},this)); 

} 

O il semplice & ma il modo sporco sarebbe quello di effettuare una richiesta sincrona invece di una richiesta asincrona per caricare i dati .

var oModel = new sap.ui.model.json.JSONModel(); 

oModel.loadData(""model/mock_applicants.json",{bAsync:false}); 

oView.setModel(oModel); 
+0

Risposta molto utile, grazie! Ammetto di aver trovato un modo di usare 'attachRequestCompleted' da solo. Tuttavia, la tua soluzione sembra più chiara. Una domanda: è possibile utilizzare il 'EventBus' di SAPUI5 invece di' jQuery.proxy() '? – SDD64

+1

puoi utilizzare EventBus invece di attivare Eventi! Il motivo dell'utilizzo di jQuery.proxy è che il valore di "this" nel gestore eventi sarà diverso. Fai una prova rimuovendo il jQuery.proxy dalla funzione del gestore di eventi e cercare di capire il valore di "this". – sakthi

Problemi correlati