Giter Site home page Giter Site logo

flight-with-child-components's People

Contributors

ahume avatar passy avatar tgvashworth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flight-with-child-components's Issues

Don't use Component.mixin if the mixin is already mixed in to the Component

This line: L54. Could perhaps be argued that this is a bug in Component.mixin.

For example, a component uses this mixin to attach a child:

/**
 * Component One
 */

var withChildComponents = require('with-child-components');
var Child = require('child');

module.exports = flight.component(componentOne, withChildComponents);

function componentOne() {
  this.attributes({
    childSelector: '.child'
  });

  this.after('initialize', function () {
    this.attachChild(Child, this.select('childSelector'));
  });
}

And is then attached by another component that uses this mixin:

/**
 * Component Two
 */

var withChildComponents = require('with-child-components');
var ComponentOne = require('component-one');

module.export = flight.component(componentTwo, withChildComponents);

function componentTwo() {
  this.attributes({
    componentOneSelector: '.component-one'
  });

  this.after('initialize', function () {
    this.attachChild(ComponentOne, this.select('componentOneSelector'));
  });
}

At this point, withChildComponents attempts to mix itself into ComponentOne for a second time. Although Flight has a guard against mixing in a mixin more than once (compose.js L30), by the time that compose.mixin call is made in Component.mixin you've created a new Component.

This is a problem because while attachTo has a guard against attaching a second instance if you end up calling it twice on a node, this.attachChild doesn't have a guard against calling Component.mixin on a Component that has already mixed in withChildComponents. This means you create a new Component and attach a new instance each time this.attachChild is called (unlike how attachTo behaves). It's not common to intentionally call attachTo (or this.attachChild) multiple times, but it's safe to do with attachTo and is what I ended up doing in a hacky POC demo that surfaced this bug.

To quick-fix the issue, I checked if withChildComponents was listed in Component.prototype.mixedIn in order to conditionally make use of Component.mixin.

var mixins = Component.prototype.mixedIn || [];
var isMixedIn = (mixins.indexOf(withChildComponents) > -1) ? true : false;
(isMixedIn ? Component : Component.mixin(withChildComponents)).attachTo(destination, attrs);

Not sure where the best place to do this is (perhaps Flight itself, I have a patch to deal with it at that end too).

cc @angus-c

README nits

maybe use a regular selector in the second example, just to drive home that the API is identical to attachTo. Also add a comment to explain we're passing a custom teardown event

//or pass a custom teardown event...
this.attachChild(AnotherChildComponent, '#anotherNode', {
  teardownOn: 'someEvent'
});

UMD bundle

Make the mixin registration a UMD bundle, so it can be used anywhere. I am specifically interested here because I use browserify to bundle everything.

Name?

Not entirely sure this is a good name. withChildren or withAttachChild maybe?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.