How and when should I load the model from database for h:dataTable



  • 问题

    I\'ve a data table as below:

    <h:dataTable value=\"#{bean.items}\" var=\"item\">
    
    

    I\'d like to populate it with a collection from the database obtained from a service method so that it is immediately presented when the page is opened during an initial (GET) request. When should I call the service method? And why?

    1. Call it before page is loaded. But how?
    2. Call it during page load. How?
    3. Call it in the getter method. But it is called multiple times.
    4. Something else?

    回答1:

    17

    Do it in bean's @PostConstruct method.

    @ManagedBean
    @RequestScoped
    public class Bean {
    
        private List<Item> items;
    
        @EJB
        private ItemService itemService;
    
        @PostConstruct
        public void init() {
            items = itemService.list();
        }
    
        public List<Item> getItems() {
            return items;
        }
    
    }
    
    

    And let the value reference the property (not method!).

    <h:dataTable value="#{bean.items}" var="item">
    
    

    In the @PostConstruct you have the advantage that it's executed after construction and dependency injection. So in case that you're using an EJB to do the DB interaction task, a @PostConstruct would definitely be the right place as injected dependencies would not be available inside a normal constructor yet. Moreover, when using a bean management framework which uses proxies, such as CDI @Named, the constructor may or may not be called the way you expect. It may be called multiple times during inspecting the class, generating the proxy, and/or creating the proxy.

    At least do not perform the DB interaction job in the getter, unless it's lazy loading and you really can't do anything else. Namely, it would be invoked during every iteration round. Calling the service method during every iteration round is plain inefficient and may end up in "weird" side effects during presentation and postbacks, such as old values from DB seemingly still sticking around in the model instead of new submitted values.

    If you rely on GET request parameters, then use <f:viewParam> and <f:viewAction> instead. If you want to preserve the model (the items property) across postbacks on the same view (e.g. CRUD table/dialog), then make the bean @ViewScoped.

    See also:

    • Why JSF calls getters multiple times
    • What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
    • How to choose the right bean scope?
    • JSF Controller, Service and DAO

    share|improve this answer

    edited May 23 '17 at 12:33

    Community♦ 111 silver badge

    answered Apr 23 '11 at 18:03

    BalusCBalusC 896k314314 gold badges32763276 silver badges33033303 bronze badges

    • What about in preRenderView or viewAction? PostConstruct might be awkward if you want to filter the database query based on parameters passed in with a get request. – Ryan Jun 18 '14 at 18:40
    • @Ryan: OP didn't ask/require a request/view parameter based action. – BalusC Jun 18 '14 at 19:08

    add a comment |



最新内容

  • I have a form I'd like to deliver via AJAX :

    <form class="form-inline ng-pristine" ng-submit="sendForm()" method="post" action="/sign_up" accept-charset="UTF-8"> $scope.sendForm = (e) -> e.preventDefault -> console.log 'sendForm()' return false

    The console.log appears, and immediately it delivers the form.

    It ignores both the e.preventDefault(), and the return false.

    AngularJS reminds me of the honey badger. It just doesn't care.

    I know I am pretty late to the party, but in case you did not figure it out yet, you can keep the action and make sure the form is not actually submitted by passing $event to the ng-submit function. Then you can use event.preventDefault(); in your controller after you do all your processing.

    So in your case it would be:

    <form class="form-inline ng-pristine" ng-submit="sendForm($event)" method="post" action="/sign_up" accept-charset="UTF-8"> $scope.sendForm = (e) -> // doing stuff e.preventDefault()

    Hope this helps.

    Well, you're not doing it the "Angular way". Angular provides a directive called ng-submit, which does that preventDefault for you (as long as you don't have an action attribute specified on your form).

    Markup (with validation!)

    <form name="myForm" ng-submit="sendForm()"> <div> <input type="text" name="name" ng-model="data.name" required/> <span ng-show="myForm.name.$error.required && myForm.name.$dirty">required</span> </div> <div> <input type="email" name="email" ng-model="data.email" required/> <span ng-show="myForm.name.$error.required && myForm.name.$dirty">required</span> <span ng-show="myForm.name.$error.email && myForm.name.$dirty">invalid email</span> </div> <button type="submit" ng-disabled="myForm.$invalid">Submit</button> </form>

    Code

    app.controller("MyCtrl", function($scope, $http) { $scope.sendForm = function (){ $http.post('/Submit/To/Url', $scope.data).success(function(data) { alert('done!'); }); }; });

    You can get the event by passing $event into your ng-click or ng-submit. It's like dependency injection, except in your expressions.

    html

    <form class="form-inline ng-pristine" ng-submit="sendForm($event)" method="post" action="/sign_up" accept-charset="UTF-8">

    coffeescript

    $scope.sendForm = (e) -> e.preventDefault() console.log 'sendForm()' false

    Here is a better solution of all of the other answers.

    Let suppose you have html5 validation required attribute attached to form elements.

    Now

    <button ng-submit="Save($event)">SEND ME</button>

    And now you function

    $scope.Save = function($event){ $event.preventDefault(); . . // may be an ajax request . return false; }

    This will not only trigger html5 validation but also this will prevent form submission redirect.

    Other way to solve this is with a directives.

    app.directive("submit", [function () { return { scope: { submit: "=" }, link: function (scope, element, attributes) { element.bind("submit", function (loadEvent) { return scope.submit(loadEvent); }); } } }]); <form submit="sendForm" method="post" action="/sign_up"> $scope.sendForm = function(e) { if ($scope.whatever) return true; else return false; };

    来源:https://stackoverflow.com/questions/14524020/angular-js-does-not-allow-preventdefault-or-return-false-to-work-on-form-submiss

    read more
  • 问题

    Why, with this program :

    <pre class="\"lang-py" prettyprint-override="">``` import sys print(\"sys.getdefaultencoding()=\'%s\'\" % (sys.getdefaultencoding(), )) with open(\"example.txt\", \"w\", encoding=\"utf-8-sig\", errors=\"replace\") as f: f.write(\"test;Ilość sztuk\\n\") with open(\"example.txt\", \"r\", errors=\"strict\") as rf: lr = rf.readline() print(\"lr=\", lr) run OK in some context, and failed in other context. example OK :

    $ python3 ./example.py
    sys.getdefaultencoding()='utf-8'
    lr= test;Ilość sztuk

    note :

    $ python3 --version
    Python 3.6.8

    example KO :

    sys.getdefaultencoding()='utf-8'
    Traceback (most recent call last):
    File "./example.py", line 9, in <module>
    lr = rf.readline()
    File "/.../python/lib/python3.6/encodings/ascii.py", line 26, in decode
    return codecs.ascii_decode(input, self.errors)[0]
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position 0: ordinal not in range(128)
    $

    note :

    $ python3 --version
    Python 3.6.8

    Contexts are ; Ubuntu 19.04, Ubuntu 18.04, Debian 9, in chroot, outside chroot, LANG is \\"en\_US.UTF-8\\" or \\"fr\_FR.UTF-8\\", no impact on success or failed In all case, Python is install by hand with same option. If you need value of some environment variable, I can give it. I search to have exact same execution in all case. 回答1: ==== 1 In Python 3, there are different encoding defaults. The one you found, sys.getdefaultencoding(), tells you the default for the methods `str.encode()` and `bytes.decode()`. As far as I know, it's always UTF-8, no matter what build or implementation of Python you use. However, if you omit the `encoding=...` parameter in a call to `open()`, then locale.getdpreferredencoding() is used; also for `sys.stdin`, `sys.stdout` (`print()`!), `sys.stderr`. The value of this default depends on the environment in which the Python interpreter is started. The details of how this value is determined varies between platforms, but often you can achieve the desired behaviour by setting the `PYTHONIOENCODING` env variable. As of Python 3.7, you can launch Python with `-X utf8` to enable UTF-8 mode. share|improve this answer answered Sep 13 at 20:08 lenzlenz 3,69144 gold badges2020 silver badges3232 bronze badges add a comment |

    read more
  • In Python 3, there are different encoding defaults. The one you found, sys.getdefaultencoding(), tells you the default for the methods str.encode() and bytes.decode(). As far as I know, it's always UTF-8, no matter what build or implementation of Python you use.

    However, if you omit the encoding=... parameter in a call to open(), then locale.getdpreferredencoding() is used; also for sys.stdin, sys.stdout (print()!), sys.stderr. The value of this default depends on the environment in which the Python interpreter is started. The details of how this value is determined varies between platforms, but often you can achieve the desired behaviour by setting the PYTHONIOENCODING env variable. As of Python 3.7, you can launch Python with -X utf8 to enable UTF-8 mode.

    read more

最新主题

推荐阅读

本站部分内容来自互联网,其发布内容言论不代表本站观点,如果其链接、内容的侵犯您的权益,烦请联系我们,我们将及时予以处理。
Powered by NodeBB | 备案号:宁ICP备15000671号