1
votes

v2.ODataModel: quelle API est la plus préférée? "bindElement" ou "read"?

J'ai défini le view.setModel (model) , j'obtiens le modèle de la vue et je demande model.read ("/ entitySet ('10000')") . Le modèle est ensuite rempli avec / entitySet ('10000') / properties .

Mais il est difficile de les affecter aux champs de vue, car maintenant dans la vue, ne fonctionne pas. Il doit s'agir de .

D'un autre côté, si je règle la liaison de contexte de la vue sur "/ entitySet ('10000')" , alors commencerait à fonctionner.

Quelle est la méthode préférée? Quand utiliser .read ?


0 commentaires

3 Réponses :


2
votes

Je n'utilise presque jamais .read si je veux utiliser les résultats d'un appel OData directement dans un contexte de liaison. La seule fois où j'utilise .read , c'est si je veux manipuler les résultats avant de faire quoi que ce soit avec eux.

Regardez cet exemple du sdk par exemple: https://ui5.sap.com/#/entity/sap.ui.table.Table/sample/sap.ui.table.sample.OData

La syntaxe de ce type de liaison est similaire à read mais avec quelques différences dans les événements et quelques types de méthodes différents en fonction de ce que vous voulez lier. La liaison à une vue par exemple utilise bindElement:

<Table rows="{properties}" />

Après cela, les champs de cette entité particulière peuvent être accédés comme .

Voici un exemple d'une de mes applications actuelles avec des événements et quelques autres paramètres d'appel:

oTable.bindRows({
  path: "properties"
});

Pour une table, c'est légèrement différent, car cela dépend de l'agrégation que vous souhaitez lier, comme

this.getView().bindElement({
  path: `/Orders('${currentOrderNumber}')`,
  parameters: {
    expand: 'Texts'
  },
  events: {
    dataRequested: _ => this.getView().setBusy(true),
    dataReceived: data => {
      if (!this.getView().getBindingContext()) {
        // navigate to `Not Found` view
      }
    },
    change: _ => this.getView().setBusy(false)
  }
});

Ce qui équivaut à:

 this.getView().bindElement("/entitySet('1000')");


0 commentaires

-2
votes

Je suis presque d'accord avec Jorg, mais pas entièrement:

Cela dépend vraiment de ce que vous essayez d'accomplir. Si vous cherchez à afficher des données depuis le backend, le moyen le plus simple est d'utiliser this.getView().bindElement()

mais si vous avez besoin de manipuler les données avant d'afficher ( comme le formatage du texte, l'affichage d'images à partir de chaînes de base64, etc.) OU si vous souhaitez créer une nouvelle entité en utilisant certaines des données existantes, OU mettre à jour les données existantes - le code this.getModel (sName) .read () > est la voie à suivre - car vous pouvez définir l'entité de lecture avec toutes ses entités profondes sur JSONModel dans successCallback et la manipuler à partir du localModel.

Si vous utilisez localModel, le dataBinding est à peu près le même dans la vue - sauf que vous devez en plus donner le nom du modèle à partir duquel prendre des données. Ainsi, par exemple, si avec succèsCallback de votre Model.read () vous définissez vos données sur Model nommé "localModel":

<Text text="{localModel>/mainPropertyName}"/>
// for displaying deep entities as List items or in Table
<List items="{localModel>/deepEntityName}">
 <StandardListItem title="{localModel>propertyNamefromDeepEntity}" />
</List>

alors dans la vue XML, vous indiquez que p>

this.getModel().read(sObjectPath, {
            urlParameters: {
                $expand: ""
            },
            success: function (oData) {
              // "localModel" is name you gave in onInit function to your new JSONMOdel, when setting it to View e.g. this.getView().setModel(oJSONMOdel, "localModel")
               this.getModel("localModel").setData(oData);
            } 
          })

D'après mon expérience de travail avec des applications plus complexes en lecture seule, j'utilise toujours Model.read ().


2 commentaires

Je ne suis pas d'accord sur votre premier point Shanir. Si vous devez manipuler des données avant de les afficher, il existe des moyens beaucoup plus simples de le faire avec les types et les formateurs. Cela supprime le besoin de créer un code de lecture et de synchronisation de modèle personnalisé - laissez simplement UI5 gérer cela pour vous.L'avantage supplémentaire est que cela vous oblige à structurer votre code en formateurs qui ne gèrent que la conversion de données et sont très testables à l'unité.


Je suppose que je n'ai pas expliqué ce que je voulais dire - je ne voulais pas dire un simple formatage de propriété, comme la date ou la coloration conditionnelle, mais plus complexe où vous devez formater des propriétés dynamiques, travailler avec des filtres dynamiques pour formater des tables arborescentes ou d'autres structures complexes. Je ne pense pas que quiconque suggère une vue de liaison ait en fait développé plus complexe que les applications en lecture seule, au moins 3 mois plus tôt, travailler directement avec oData avait un comportement si ennuyeux! Et quiconque a eu du mal avec les exigences des clients dira la même chose. même les APPS SAP standard complexes utilisent des modèles locaux, et cela en dit beaucoup!



3
votes

Il est toujours important d'être plus expressif. Utilisez l'API spécialement conçue pour effectuer cette tâche.

Comparaison des deux variantes:

  1. myModel.read ( sPath ) avec text="{/path/property}"
  2. myControl.bindElement ( sPath ) avec text="{property}"

Je serais perplexe au sujet du premier appel alors que lors du deuxième appel, je saurais exactement ce que vous voulez accomplir (vous voulez lier l'élément . Alternativement, bindObject peut être également utilisé).

La même chose s'applique au framework. Puisque vous dites exactement ce que vous voulez réaliser, le framework peut améliorer son comportement en fonction de votre intention. Par exemple: dans le gestionnaire (route) PatternMatched lorsque l'utilisateur accède à la même page, .bindElement avec le même chemin ne déclenchera pas une autre requête puisque le modèle stockait déjà l'entité de l'appel précédent. Il peut afficher le résultat immédiatement.
Avec .read , cependant, le framework ne sait pas ce que vous voulez réaliser, il envoie donc la requête immédiatement quel que soit l'état de l'application.

De plus, la 1ère variante est tout sauf à l'épreuve du temps. Il repose sur les résultats mis en cache. C'est presque un effet secondaire que cela fonctionne du tout. Le problème est qu'il n'y a aucune garantie que ce comportement continuera à fonctionner dans les versions ultérieures. De plus, il n'y aura pas de méthode read dans ODataModel V4.


TL; DR

bindElement or bindObject

  • Ne crée pas de contexte à partir de la réponse. La répétition de .read ("") envoie toujours une nouvelle requête.
  • Moins expressif. Encourage les développeurs d'applications à travailler avec un modèle côté client (par exemple JSONModel).
  • L'application perd la conscience du contexte, ce qui augmente le coût total de possession, moins évolutive

v2.ODataModel#read

  • Crée un contexte à partir de la réponse et le stocke en interne afin que la même requête puisse renvoyer les données immédiatement.
  • exprime clairement l'intention; l'application ainsi que le framework peuvent fonctionner avec les API existantes.
  • Plus évolutif: v4. ODataModel ne prend pas en charge la lecture manuelle. Imaginez que vous ayez construit vos applications avec l'approche v2ODataModel.read - jsonModel.setData , et que vous devez migrer vers v4 . S'amuser. :)


Je pense honnêtement que v2.ODataModel # read n'aurait jamais dû devenir une méthode publique. Je n'encouragerais personne à utiliser .read à l'exception de lors de la lecture manuelle de la valeur de $ count .

Si le les valeurs d'entité doivent être formatées, il existe des formateurs et des types de liaison prêts à l'emploi qui sont également faciles à étendre.

Si l'application a besoin de restructurer le corps de la réponse, c'est généralement le signe d'une mauvaise conception de le modèle de données ou le service non conforme à la spécification OData.


0 commentaires