Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    heeplr
    @heeplr
    Is there a clean way to share a single Model among several views? I have an API endpoint that gives a list. I want to generate <options> from that list for multiple <selects> but only send one request to the API.
    Julian Gonggrijp
    @jgonggrijp

    @heeplr There is nothing against using the same model in multiple views, in fact I think you're encouraged to do that.

    I have a big application with a scenario somewhat like yours. The data model itself is described in data, so we fetch it from the server. Then we use it in many places to present the available options to our users.

    heeplr
    @heeplr
    hm, I tried setting "this.model = myModel" in initialize() and passing MyView({ model: myModel }). I'm .fetch() ing the model in onRender() if .length == 0. That results in one request for every MyView instance.
    I probably have a bug somewhere, will dig a bit more and come up with a test case eventually
    Julian Gonggrijp
    @jgonggrijp
    @heeplr yeah so the easy solution is probably not to fetch in the view, but in other code in advance.
    heeplr
    @heeplr
    i like to fetch() when the first View is rendered.
    What I don't understand is why model.length doesn't change after the first fetch({wait:true}) if it's shared by reference
    there must be some sort of _.clone() in between
    heeplr
    @heeplr
    it seems to boil down that "const foo = MyCollection(); foo.fetch({ wait: true })" doesn't actually change "foo.length" or add any models.
    Julian Gonggrijp
    @jgonggrijp
    @heeplr foo.fetch does a request so the response arrives only async. You have to listen for a sync event of await the promise that it returns before you'll see any models.
    heeplr
    @heeplr
    even with { wait: true } ? hm
    Julian Gonggrijp
    @jgonggrijp
    Yes, wait only ensures that models are added after the response instead of before. The response itself is still async.
    and I actually don't think wait does anything with fetch, I think it was more intended for create and destroy.
    heeplr
    @heeplr
    ah yeah, you mentioned that both are async
    heeplr
    @heeplr
    @jgonggrijp a few days ago you said the easyiest way to use a single model for multiple views would be to fetch it outside of the view (which works fine). But I found no way to do it when the view is rendered.
    Can you (or anyone else) gimme a hint on how to approach that?
    Doing it outside of the View(s) sends a request much more often than doing it on the first render of the first View. I'd like to avoid that if possible.
    heeplr
    @heeplr
    ahh, I think I found an easy solution: I can use a "fetching" flag in the model that prevents additional fetches if there's already one ongoing
    Julian Gonggrijp
    @jgonggrijp
    @heeplr Yes you'd need something like that. You can also have a function wrapped in _.once or use a promise.
    heeplr
    @heeplr
    cool, thanks.
    Maybe I should read the underscore docs to improve my backbone fu
    Julian Gonggrijp
    @jgonggrijp
    @heeplr With Underscore being a foundation for Backbone, I can definitely recommend that. Also good for general maintainability outside of Backbone, though.

    To get back to an earlier comment of you, though...

    Doing it outside of the View(s) sends a request much more often than doing it on the first render of the first View. I'd like to avoid that if possible.

    Actually, I don't see why this should be the case.

    heeplr
    @heeplr
    Well, in my case "outside" of the view means somewhere in the parent view or where I setup Views. That is run on every page load. I don't see another way.
    That in turn sends a ton of API requests loading data that might never be displayed
    with _.once() i can now conveniently and cleanly fetch() in onRender(), fetching the data only when it's needed and only once.
    Julian Gonggrijp
    @jgonggrijp
    I see. I thought you meant the model might be fetched multiple times within a single application run.
    heeplr
    @heeplr
    ah, no. didn't make it clear enough.
    Julian Gonggrijp
    @jgonggrijp
    But I now understand that you meant that "exactly once" is already potentially too much. :-)
    Another trick you can use, which is a bit more sophisticated, is to use a request/reply on a Backbone.Radio channel to obtain a previously fetched model/collection if available and have it fetched on the fly otherwise. I've been using this pattern a lot in my largest project so far. The advantage is that multiple views need not explicitly share the same model/collection, so it is easier to test them in isolation (also because the radio channel is a great access point to plug a mock).
    heeplr
    @heeplr
    hm, didn't think about testing, yet. That sounds like a clean solution.
    Julian Gonggrijp
    @jgonggrijp
    I made a proposal to put prototypes first in Backbone v2. At this stage, it's just an idea, because v2 isn't around the corner yet. Thoughts welcome.
    jashkenas/backbone#4245
    Oh by the way, I maintain Backbone now. :-)
    dimtabu
    @taburetkin
    i wish remote api will be optional plugin in bb2
    Julian Gonggrijp
    @jgonggrijp
    @taburetkin I'm open to the idea. Is there an issue ticket for it yet?
    dimtabu
    @taburetkin
    not yet, should i create it?
    Julian Gonggrijp
    @jgonggrijp
    Please feel welcome if you like, that's what ticketing systems are for!
    dimtabu
    @taburetkin
    done
    heeplr
    @heeplr
    what could be the reason I get "Uncaught TypeError: this.model.get(...) is undefined" on my Model instance? Accessing this.model.attributes directly works without problems.
    Julian Gonggrijp
    @jgonggrijp
    @heeplr maybe .get is defined but the result of .get(...) is undefined? Meaning, you retrieve an undefined value and then try to access a property on it in a subsequent step?
    I'm just blind-guessing here. For certainty, step through your code with a debugger or show us the full affected line of code.
    heeplr
    @heeplr
    @jgonggrijp pretty sure it's get itself. Since "defaults:" are set for the Model, those should be returned so that get() results should never be undefined.
    I'll .clone() the model and triple check if get method is defined, just to be sure.
    Julian Gonggrijp
    @jgonggrijp
    In any case, if the .get method is somehow overridden to be undefined (or if the method is somehow deleted from the prototype), then that wouldn't be explained by attributes being absent.
    Julian Gonggrijp
    @jgonggrijp
    @heeplr Would you mind sharing the conclusion of your investigation with us?
    heeplr
    @heeplr
    @jgonggrijp I have no clue honestly. I tracked it down to webpack but that's just a guess. The error was gone when I rebuilt the project.
    I hope it's solved but if I encounter it again, i'll investigate further in the debugger.
    Julian Gonggrijp
    @jgonggrijp
    Thanks @heeplr
    heeplr
    @heeplr
    thank you for your help. appreciate it a lot.