Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    dimtabu
    @taburetkin

    What if the CollectionView has some HTML of its own, which needs to change after the first render?

    i think that this task everyone solves in its own way
    by my experience (and this is just my opinion, nothing more)
    its bad if my view has children views and its own raw html depended on some state - this means that i was too lazy to decouple it in a separate view

    Julian Gonggrijp
    @jgonggrijp

    The last SearchForm example from my introduction is such a case:

    class SeachForm extends CompositeView {
        // initialize is exactly the same as above
        initialize() {
            this.input = new QueryField({model: this.model});
            this.button = new SubmitButton();
            this.input.render();
            this.button.render();
        }
    
        template({title}) {
            return `
                <h1>${title}</h1>
                <div class="container"></div>
            `;
        }
    
        renderContainer() {
            this.$el.html(this.template(this.model.toJSON()));
            return this;
        }
    }

    On change:title of this.model, the SearchForm needs to redraw, but the QueryField and the SubmitButton can stay the same.

    If I can avoid redrawing the children, then I prefer to do so. The children might be costly to render.

    dimtabu
    @taburetkin

    the SearchForm needs to redraw,

    why?

    Julian Gonggrijp
    @jgonggrijp

    its bad if my view has children views and its own raw html depended on some state - this means that i was too lazy to decouple it in a separate view

    Why wouldn't a composed view be allowed to have some state of its own?

    The SearchForm needs to redraw because its template depends on the title of the model.
    dimtabu
    @taburetkin
    ok
    i will answer on both because this is about the same thing.
    Julian Gonggrijp
    @jgonggrijp
    I'm curious. I think we're getting to some fundamental principles now. :-)
    dimtabu
    @taburetkin
    const Title= View.extend({ 
      tagName: 'h1', 
      template: '<%= title %>',
      modelEvents: {
        'change:title': 'render'
      }
    });
    const MainView = CollectionView.extend({
      onRender() {
         this.addChildView(new Title({ model: this.model }));
         this.addChildView(new Input());
         this.addChildView(new Button());
      }
    });
    in this case only one view will re-rendered - the Title one.
    rest stay unchanged
    Julian Gonggrijp
    @jgonggrijp
    This works, but I'm forced to factor out the stateful part and put it at the bottom of the hierarchy. Why can't I just have a stateful view with subviews?
    Isn't this just another respect in which backbone-fractal is more flexible than Marionette?
    dimtabu
    @taburetkin
    as i told you before mn has special api to detach/atach any child view
    so, actually you can do that.
    its just not default behavior
    and i did that in some of my apps
    thats why i personally think that this is bad idea.
    and now i just do not do such things in my apps.
    Julian Gonggrijp
    @jgonggrijp
    So what went wrong in those apps?
    dimtabu
    @taburetkin
    the most important thing is "do things in a one way" - everything detach/atach, OR everything destroy/render.
    i didn't.
    and sometimes I got shot myself in the heel.
    the second thing is that detach/atach behavior more troublesome
    Julian Gonggrijp
    @jgonggrijp
    That's very true. I've shot myself in the foot with those things, too. But this is exactly what led me to create backbone-fractal. backbone-fractal consistently does detach/attach, and fully automatically at that. It also automatically destroys all child views at the end of the lifetime of the parent view.
    dimtabu
    @taburetkin
    did you tried to test performance destroy/render against atach/detach ?
    i did, and do not find any significant difference
    i mean that its pretty hard to make something working extremely slow just because of destroy/render behavior.
    Julian Gonggrijp
    @jgonggrijp
    I didn't run any benchmarks. Even if the performance difference is small, though, the added flexibility is still there and I'm not seeing the disadvantage of that yet.
    By the way, I added a comparison table to the Readme: https://gitlab.com/jgonggrijp/backbone-fractal/blob/feature/gentle-introduction/README.md#comparison-with-marionette. If you see a factual error, please let me know.
    dimtabu
    @taburetkin
    well, ok ))
    dimtabu
    @taburetkin
    how to force to re-render all children too in your lib?
    (You can also do it at another time, the line of code you need is the same.)
    dimtabu
    @taburetkin
    ah, i see
    Julian Gonggrijp
    @jgonggrijp
    dimtabu
    @taburetkin
    the last one works
    also, you may find this interesting
    dimtabu
    @taburetkin
    this lib solves view partial render task.
    but personally i prefer to split stateful html in separate views and never used it
    Julian Gonggrijp
    @jgonggrijp
    I heard of that one. I find it very interesting, but like you, I haven't used it yet. :-)
    It's more a two-way binding kind of library that a composition library, though.
    dimtabu
    @taburetkin
    const { Model } = Backbone;
    
    const emiter = new Model();
    const context = {};
    const context2 = {};
    
    function foo() {
      let whichOne = 'none of contexts';
      if (this === context) {
        whichOne = 'context';
      }
      if (this === context2) {
        whichOne = 'context2';
      }
      console.log('`this` is ' + whichOne);
    }
    emiter.on({ foo }, context, context2);
    emiter.on({ bar: foo }, context);
    emiter.trigger('foo'); //`this` is context2
    emiter.trigger('bar'); //`this` is context
    Can someone shed light on this? i really want to understand the reason why it is working like that
    at this point it seems odd for me
    Paul Falgout
    @paulfalgout
    The first on you're using isn't a valid combination. The two available APIs are on([object], [context]) and on([name], [callback], [context]) So on([object], [context], [context]) may be acting strangely, but it is not a valid use of the method.
    dimtabu
    @taburetkin
    yes
    but there is a test against exactly the first case
    it ensures that your third argument should be a context
    i found out this when working with backbone events tests. and this behavior seems to me incorrect and unexpected
    but i think there was a reason why its working like this. i just can't get why
    Julian Gonggrijp
    @jgonggrijp

    @taburetkin if you really want to "see" how it happens, step trough it with a debugger.

    I agree with @paulfalgout, though. If you call Backbone.Events.on with an event map and two other arguments, you are the one who is behaving in an unexpected way, not Backbone. Once you break the contract, Backbone has a legal right to do anything, including using the third argument as context, kidnapping your dog and scratching your car with a potato.

    (Joke borrowed from Learn you a Haskell for great good! Nice book.)

    dimtabu
    @taburetkin
    i was not almost clear
    i am working right now on some events library which should be compatible with backbone events.
    so, i literraly knows how exactly backbone events works.
    and when i run all backbone tests against my lib i faced with this one case.
    and i HAVE to do strange things just to pass this test and i dont understand the nature of this
    in general the question is about tests
        obj.off().on({
          a: function() {
            assert.strictEqual(this, context, 'will not override explicit `context` param');
          }
        }, this, context).trigger('a');
    dimtabu
    @taburetkin
    maybe this is for this model.on({ ... }, null, context) but it's just a guess
    @jgonggrijp @paulfalgout ^
    Julian Gonggrijp
    @jgonggrijp
    @taburetkin I see. Yes, it seems to be by design. Maybe in order to facilitate mediators that don't know in advance whether the client will be passing a name-handler pair or an event map?
    dimtabu
    @taburetkin
    i believe there should be something in the docs to clarify this case.
    Paul Falgout
    @paulfalgout
    @taburetkin added here: jashkenas/backbone#3603