The Road to Ember 2.0 RFC #15

Merged
merged 2 commits into from Jun 7, 2015

Projects

None yet
@tomdale
Member
tomdale commented Nov 3, 2014
  • Start Date: 2014-12-03
  • RFC PR: (leave this empty)
  • Ember Issue: (leave this empty)

The Road to Ember 2.0

Intro

Today, we're announcing our plan for Ember 2.0. While the major version bump gives us the opportunity to simplify the framework in ways that require breaking changes, we are designing Ember 2.0 with migration in mind.

This is not a big-bang rewrite; we will continue development on the master branch, and roll out changes incrementally on the 1.x release train. The 2.0.0 release will simply remove features that have been deprecated between now and then. Our goal is that you can move your Ember app to 2.0 incrementally, one sprint at a time.

This RFC captures the results of the last two core team face-to-face meetings, where we discussed community feedback about the future of the project. While it explains the high-level goals and tries to paint a picture of how all the pieces fit together, this document will be updated over time with links to individual RFCs that contain additional implementation detail.

We plan to flesh out these more-detailed RFCs in the next few weeks, as the discussion here progresses, before finalizing this plan.

We are announcing Ember 2.0 through our community RFC process in advance of a release, both so our proposals can be vetted by the community and so the community can understand the goals and contribute their own ideas back.

Motivation

Stability without Stagnation

Ember is all about identifying common patterns that emerge from the web development community and rolling them into a complete front-end stack. This makes it easy to get started on new projects and jump into existing ones, knowing that you will get a best-of-breed set of tools that the community will continue to support and improve for years to come.

In the greater JavaScript community, getting the latest and greatest often means rewriting parts of your apps once a year, as the community abandons existing solutions in search of improvements. Progress is important, but so is ending the constant cycle of writing and rewriting that plagues so many applications.

The Ember community works hard to introduce new ideas with an eye towards migration. We call this "stability without stagnation", and it's one of the cornerstones of the Ember philosophy.

Below, we introduce some of the major new features coming in Ember 2.0. Each section includes a transition plan, with details on how we expect existing apps to migrate to the new API.

When breaking changes are absolutely necessary, we try to make those changes ones you can apply without too much thought. We call these "mechanical" refactors. Typically, they'll involve a change to syntax without changing semantics. These are significantly easier to adopt than those that require fundamental changes to your application architecture.

To further aid in these transitions, we are planning to add a new tab to the Ember Inspector that will list all deprecations in your application, as well as a list of the locations in the source code where the deprecated code was triggered. This should serve as a convenient "punch list" for your transitional work.

Every member of the core team works on up-to-date Ember applications, and we feel the tension between stability and progress acutely. We want to deliver cutting-edge products, but need to keep shipping, and many companies that have adopted Ember for their products tell us the same thing.

Big Bets

In 2014, we made big bets in two areas, and they've paid off.

The first bet was on open standards: JavaScript modules, promises and Web Components. We started the year off with globals-based apps, callbacks and "views", and incrementally (and compatibly) built towards standards-based solutions as those standards solidified.

The second bet was that the community was as tired as we were of hand-rolling their own build scripts for each project. We've invested heavily in Ember CLI, giving us a single tool that unifies the community and provides a venue for disseminating great ideas.

In Ember 2.0, Ember CLI and ES6 modules will become first-class parts of the Ember experience. We will update the website, guides, documentation, etc. to teach new users how to build Ember apps with the CLI tools and using JavaScript's new module syntax.

While globals-based apps will continue to work in 2.0, we may introduce new features that rely on either Ember CLI or ES6 modules. You should begin moving your app to Ember CLI as soon as possible.

All of the apps maintained by the Ember core team have been migrated to Ember CLI, and we believe that most teams should be able to make the transition incrementally.

Learning from the Community

We're well aware that we don't have a monopoly on good ideas, and we're always analyzing competing frameworks and libraries to discover great ideas that we can incorporate.

For example, AngularJS taught us the importance of making early on-ramp easy, how cool directives/components could be, and how dependency injection improves testing.

We've been analyzing and discussing React's approach to data flow and rendering for some time now, and in particular how they make use of a "virtual DOM" to improve performance.

Ember's view layer is one of the oldest parts of Ember, and was designed for a world where IE7 and IE8 were dominant. We've spent the better part of 2014 rethinking the view layer to be more DOM-aware, and the new codebase (codenamed "HTMLBars") borrows what we think are the best ideas from React. We cover the specifics below.

React's "virtual DOM" abstraction also allowed them to simplify the programming model of component-based applications. We really like these ideas, and the new HTMLBars engine, landing in the next Ember release, lays the groundwork for adopting the simplified data-flow model.

In Ember 2.0, we will be adopting a "virtual DOM" and data flow model that embraces the best ideas from React and simplifies communication between components.

Interestingly, we found that well-written Ember applications are already written with this clear and direct data flow. This change will mostly make the best patterns more explicit and easier for developers to find when starting out.

A Steady Flow of Improvement

Ember 1.0 shipped over a year ago and we have continued to improve the framework while maintaining backwards-compatibility. We are proud of the fact that Ember apps tend to track released versions.

You might expect us to do Ember 2.0 work on a separate "2.0" branch, accumulating features until we ship. We aren't going to do that.

Instead, we plan to do the vast majority of new work on master (behind feature flags), and land new features in 1.x as they become stable.

The 2.0.0 release will simply remove the cruft that naturally builds up when maintaining compatibility with old releases.

If we add features that change Ember idioms, we will add clear deprecation warnings with steps to refactor to new patterns.

Our goal is that, as much as possible, people will be able to boot up their app on the last 1.x version, update to the latest set of idioms by following the deprecation prompts, and have things working on 2.0.

Because going from the last version of Ember 1.x to Ember 2.0 will be just another six-week release, there simply won't be much time for us to make it an incredibly painful upgrade. ;)

Simplifying Ember Concepts

Ember evolved organically from a view-layer-only framework in 2011 into the route-driven, complete front-end stack it is today. Along the way, we've accumulated several concepts that are no longer widely used in idiomatic Ember apps.

These vestigial concepts make file sizes larger, code more complex, and make Ember harder to learn.

Ember 2.0 is about simplification. This lets us reduce file sizes, reduce code complexity, and generally make Ember apps easier to pick up and maintain.

The high-level set of improvements that we have planned are:

  • More intuitive attribute bindings
  • New HTML syntax for components
  • Block parameters for components
  • More consistent template scope
  • One-way data binding by default, with opt-in to mutable, two-way bindings
  • More explicit communication between components, which means less implicit communication via two-way bindings
  • Routes drive components, instead of controller + template
  • Improved actions that are invoked inside components as simple callbacks

In some sections, we provide estimates for when a feature will land. These are our best-guesses, but because of the rapid-release train model of Ember, we may be off by a version or two.

However, all features that are slated for "before 2.0" will land before we cut over to a major new version.

More Intuitive Attribute Bindings

Today's templating engine is the oldest part of Ember.js. Under the hood, it generates a string of HTML and then inserts it into the page.

One unfortunate consequence of this architecture is that it is not possible to intuitively bind values to HTML attributes.

You would expect to be able type something like:

<a href="{{url}}">Click here</a>

But instead, in today's Ember, you have to learn about and use the bind-attr helper:

<a {{bind-attr href=url}}>Click here</a>

The new HTMLBars template engine makes bind-attr a thing of the past, allowing you to type what you mean. It also makes it possible to express many attribute-related concepts simply:

<a class="{{active}} app-link" href="{{url}}.html">Click here</a>

Transition Plan

The HTMLBars templating engine is being developed on master, and parts of it have already landed in Ember 1.8. Doing the work this way means that the new engine continues to support the old syntax: your existing templates will continue to work.

The improved attribute syntax has not yet landed, but we expect it to land before Ember 1.10.

We do not plan to remove support for existing templating syntax (or no-longer-necessary helpers like bind-attr) in Ember 2.0.

More Intuitive Components

In today's Ember, components are represented in your templates as Handlebars "block helpers".

The most important problem with this approach is that Handlebars-style components do not work well with attribute bindings or the action helper. In short, a helper that is meant to be used inside an HTML tag cannot be used inside a call to a component.

Beginning in Ember 1.11, we will support an HTML-based syntax for components. The new syntax can be used to invoke existing components, and new components can be called using the old syntax.

<my-video src={{movie.url}}></my-video>

<!-- equivalent to -->

{{my-video src=movie.url}}

Transition Plan

The improved component syntax will (we hope) land in Ember 1.11. You can transition existing uses of {{component-name}} to the new syntax at that time. You will likely benefit by eliminating uses of computed properties that can now be more tersely expressed using the interpolation syntax.

We have no plans to remove support for the old component syntax in Ember 2.0.

Block Parameters

In today's templates, there are two special forms of built-in Handlebars helpers: #each post in posts and #with post as p. These allow the template inside the helper to retain the parent context, but get a piece of helper-provided information as a named value (such as post in the previous examples).

{{#with contact.person as p}}
  {{!-- this block of code is still in the parent's scope, but
        the #with helper provided a `p` name with a
        helper-provided value --}}
  <p>{{p.firstName}} {{p.lastName}}</p>

  {{!-- `title` here refers to the outer scope's title --}}
  <p>{{title}}</p>
{{/with}}

Today, this capability is hardcoded into the two special forms, but it can be useful for other kinds of components. For example, you may have a calendar component (ui-calendar) that displays a specified month.

The ui-calendar component may want to allow users to supply a custom template for each day in the month, but each repetition of the template will need information about the day it represents (its day of the week, date number, etc.) in order to render it.

With the new "block parameters" feature, any component will have access to the same capability as #each or #with:

<ui-calendar month={{currentMonth}} as |day|>
  <p class="title">{{day.title}}</p>
  <p class="date">{{day.date}}</p>
</ui-calendar>

In this case, the ui-calendar component iterates over all of days in currentMonth, rendering each instance of the template with information about which date it should represent.

We also think that this feature will be useful to allow container components (like tabs or forms) to supply special-case component definitions as block params. We are still working on the details, but believe that an approach along these lines could make these kinds of components simpler and more flexible.

Transition Plan

Block parameters will hopefully land in 1.12, and at that point the two special forms for {{each}} and {{with}} will be deprecated. You should refactor your templates to use the new block parameters syntax once it lands, as it is a purely mechanical refactor.

We have no plans to remove support for the {{each}} and {{with}} special forms in Ember 2.0.

More Consistent Handlebars Scope

In today's Ember, the each and with helpers come in two flavors: a "context-switching" flavor and a "named-parameter" flavor.

{{#each post in posts}}
  {{!-- the context in here is the same as the outside context,
        and `post` references the current iteration --}}
{{/each}}

{{#each posts}}
  {{!-- the context in here has shifted to the individual post.
        the outer context is no longer accessible --}}
{{/each}}

This has proven to be one of the more confusing parts of the Ember templating system. It is also not clear to beginners which to use, and when they choose the context-shifting form, they lose access to values in the outer context that may be important.

Because the helper itself offers no clue about the context-shifting behavior, it is easy (even for more experienced Ember developers) to get confused when skimming a template about which object a value refers to.

In Ember 1.10, we will deprecate the context-shifting forms of #each and #with in favor of the named-parameter forms.

Transition Plan

To transition your code to the new syntax, you can change templates that look like this:

{{#each people}}
  <p>{{firstName}} {{lastName}}</p>
  <p>{{address}}</p>
{{/each}}

with:

{{#each people as |person|}}
  <p>{{person.firstName}} {{person.lastName}}</p>
  <p>{{person.address}}</p>
{{/each}}

We plan to deprecate support for the context-shifting helpers in Ember 1.10 and remove support in Ember 2.0. This change should be entirely
mechanical.

One-Way Bindings by Default

After a few years of having written Ember applications, we have observed that most of the data bindings in the templating engine do not actually require two-way bindings.

When we designed the original templating layer, we figured that making all data bindings two-way wasn't very harmful: if you don't set a two-way binding, it's a de facto one-way binding!

We have since realized (with some help from our friends at React), that components want to be able to hand out data to their children without having to be on guard for wayward mutations.

Additionally, communication between components is often most naturally expressed as events or callbacks. This is possible in Ember, but the dominance of two-way data bindings often leads people down a path of using two-way bindings as a communication channel. Experienced Ember developers don't (usually) make this mistake, but it's an easy one to make.

When you use the new component syntax, the {{}} interpolation syntax defaults to creating one-way bindings in the components.

<my-video src={{url}}></my-video>

In this example, the component's src property will be updated whenever url changes, but it will not be allowed to mutate it.

If a template wishes to allow the component to mutate a property, it can explicitly create a two-way binding using the mut helper:

<my-video paused={{mut isPaused}}></my-video>

This can help ease the transition to a more event-based style of programming.

It also eliminates the boilerplate associated with an event-based style when working with form controls. Instead of copying state out of a model, listening for callbacks, and updating the model, the input helper can be given an explicit mutable binding.

<input value={{mut firstName}}>
<input value={{mut lastName}}>

This is similar to the approach taken by React.Link, but we think that the use-case of form helpers is sufficiently common to make it ergonomic.

Transition Plan

The new one-way default is triggered by the use of new component syntax. This means that component invocations in existing templates will continue to work without changes.

When transitioning to the new HTML-based syntax, you will likely want to evaluate whether bindings are actually being mutated, and avoid using mut for values that the component never changes. This will make it easier for future readers of your template to get an understanding of what properties might be changed downstream.

To preserve the same semantics during a refactor to the new HTML-based syntax, you can simply mark all bindings as mut.

{{!-- these are semantically equivalent --}}

{{my-video src=movie.url paused=controller.isPaused}}

<my-video src={{mut movie.url}} paused={{mut controller.isPaused}}>
</my-video>

While the above example preserves the same mutability semantics, it should be clear that the video player component should never change the url of the movie model.

To make sure you get an exception should this ever happen, simply remove the mut:

<my-video src={{movie.url}} paused={{mut controller.isPaused}}>
</my-video>

We have no plans to remove the old-style component syntax in Ember 2.0, so the semantics of existing component invocations will not change.

Separated Component Parameters

In today's Ember, parameters passed to components as attributes become properties of the component itself, putting them in the same place as other internal state.

This can be somewhat confusing, because it may not be obvious to the reader of a component's JavaScript or template which values are internal, and which are passed in as part of the public API.

To remind themselves, many Ember users write their components like this:

export default Component.extend({
  /* Public API */

  src: null,
  paused: null,
  title: null,

  /* Internal */
  scrubber: null
})

It can also be unclear how to react to a change in the external properties. It is possible to use observers for this purpose in Ember, but observers feel low-level and do not coordinate very well with the rendering process.

To reduce confusion, we plan to move external attributes into a new attrs hash.

If you invoke a component like this:

<my-video src={{movie.url}}></my-video>

then the my-video component accesses the passed-in src attribute as this.attrs.src.

We also plan to provide lifecycle callbacks (modelled after React's lifecycle callbacks) for changes to attrs that will integrate with the rendering lifecycle. We plan to supplement the API with callbacks for changes in individual properties as well.

Transition Plan

In Ember 1.10, we will begin installing provided attributes in the component's attrs hash. If a provided attribute is accessed directly on the component, a deprecation warning will be issued.

In applications, you should update your component JavaScript and templates to access provided attributes via the component's attrs property.

In Ember 2.0, we will stop setting attributes as properties on the component itself.

We will also provide a transitional mixin that Ember addons can use that will make provided attributes available as attrs.*. This will allow add-ons to move to the new location, while maintaining support for older versions of Ember. We expect people to upgrade to Ember 1.10 relatively quickly, and do not expect addons to need to maintain support for Ember 1.9 indefinitely.

Routeable Components

Many people have noticed that controllers in Ember look a lot like components, but with an arbitrary division of responsibilities. We agree!

In current versions of Ember, when a route is entered, it builds a controller, associates a model with it, and hands it off to an (old-style) view for rendering. The view itself is invisible; you just write a template with the correct name.

We plan to transition to: when a route is entered, it renders a component, passing along the model as an attr. This eliminates a vestigial use of old-style views, and associates the top-level template with a regular component.

Transition Plan

Initially, we will continue to support routing to a controller+template, so nothing will break. Going forward, routes will route to a component instead.

In order to do that refactoring, several things will change:

  • Instead of referring to model properties directly (or on this), you will refer to them as model.propName.
  • Similarly, computed properties that move to your component will need to depend on model.propName if they are migrated from an ObjectController.
  • In both cases, the short version is that you can no longer rely on the proxying behavior of ObjectController or ArrayController, but you can remedy the situation by prefixing model. to the property name.
  • Unlike controllers, top-level components do not persist across navigation. Persistent state should be stored in route objects and passed as initial properties to routable components.
  • In addition to the asynchronous model hook in routes, routes will also be able to define a attrs hook, which can return additional asynchronous data that should be provided to the component.
  • Routeable Components should be placed in a "pod" naming convention. For example, the component for the blog-post route would be app/blog-post/component.js.

We plan to land support for routeable components in Ember 1.12, and deprecate routeable controllers at the same time. We plan to remove support for routeable controllers in Ember 2.0. This will allow you to move your codebases over to routeable components piecemeal before making the jump to 2.0.

We will also provide an optional plugin for Ember 2.0 apps that restores existing behavior. This plugin will be included in the Ember automated test suite to ensure that we do not introduce accidental regressions in future releases on the 2.x series.

We realize that this is the change has the largest transitional cost of all the planned features, and we plan to dedicate time to the precise details in the full RFC on this topic.

Improving Actions

Today's components can communicate with their parent component through actions. In particular, the sendAction method allows a child component to invoke a named action on the parent (inside of the actions hash).

Part of the reason for this API was a limitation in the original Handlebars syntax:

{{!-- we can't get too fancy with the value of key-press --}}
{{input key-press="valueChanged"}}

In this example, when the input component calls this.sendAction('key-press'), it invokes the valueChanged action on its parent component.

With the new HTML syntax for components, we have more flexibility:

<input key-press={{action "valueChanged"}}>

This will package up the parent's valueChanged action (in the actions hash) as a callback function that is available to the child component as this.attrs['key-press'].

export default Ember.Component.extend({
  keypress: function(event) {
    this.attrs['key-press'](event.target.value);
  }
});

The benefit of this approach is twofold:

  • Actions are no longer treated specially in the component API. They are simply properties packaged up to be called by the child component.
  • It is possible to pass an alternative function as the key-press, reducing the child component's knowledge of what the callback is doing. This has testing and abstraction benefits.

Transition Plan

We will continue to support the sendAction API for the forseeable future in today's Handlebars syntax.

When calling an existing component with new HTMLBars syntax, you do not need to change your existing actions hash. You should change syntax that looks like this:

{{video-player playing="playingBegins"}}

To this:

<video-player playing={{action "playingBegins"}}>

The video-player component's internal use of sendAction will work with both calling styles.

New components should use this.attrs.playing(), but existing components that want to continue supporting legacy callers should continue to use sendAction for now. The sendAction API will seamlessly support both calling styles, and will be supported for the forseeable future.

// instead of
this.sendAction('progress', value);

// new code can use
this.attrs.progress(value);

Onward

Version 2.0 marks the transformation of Ember from simply an MVC framework to a complete front-end stack. Between Ember's best-in-class router, revamped components with virtual DOM, easy-to-use build tools, and a growing ecosystem that makes taking advantage of additional libraries a breeze, there's no better way to get started and stay productive developing web apps today.

Hopefully, this plan demonstrates that staying on the cutting-edge can be done without rewriting your app. There are a huge number of Ember apps in production today, and we're looking forward to a time in the very near future where they can start to take advantage these new features.

Expect to see many more RFCs covering these features in depth soon (including a roadmap for Ember Data 1.0). We look forward to hearing your feedback!

@Robdel12
Robdel12 commented Nov 3, 2014

This is amazing.

In Ember 2.0, Ember CLI and ES6 modules will become first-class parts
of the Ember experience. We will update the website, guides, documentation,
etc. to teach new users how to build Ember apps with the CLI tools and
using JavaScript's new module syntax.

I'd love to help. Any specifics on how to?

@fivetanley
Member

A side note about migrating: please start opening use case issues here: https://github.com/fivetanley/ember-cli-migrator

@igorT and I are building a command line tool to help you migrate as we have the time. It's currently not usable from the command line (you might be able to use a custom node script), but we're interested in the following use cases:

  • Detecting third party dependencies like moment, jQuery UI, etc and doing the import statements for you.
  • migrating tests over

and probably some other stuff I'm forgetting.

I'm hoping to get something usable out the door by Black Friday (November 28th, 2014, the day after thanksgiving). I'd love to here the use cases of people trying to migrate on that repository (please don't respond to this comment here)

@Pradeek
Pradeek commented Nov 3, 2014

Many people have noticed that controllers in Ember look a lot like
components, but with an arbitrary division of responsibilities. We
agree!

I've never understood the real pull of writing everything as a component. Going by what web components are defined like, I would imagine components are reusable generic standalone templates+logic. Generally a web app involves using multiple such components in some combination to get the business logic required. What advantage does changing "everything" into a component actually provide? Is it just a matter of "cleanliness" or is there some other benefit? Most routes I imagine are not going to be reusable, so can you guys explain the rationale on this a bit more?

@James1x0
James1x0 commented Nov 3, 2014

@Pradeek I have to agree with you. Components are reusable and drop-in. Routes just aren't reusable in nature. I would like the rationale for this change as well.

@jacefarm
jacefarm commented Nov 3, 2014

👍

@nybblr
nybblr commented Nov 3, 2014

Great thoughts, really excited to see where Ember is headed.

My only concern is the CLI: while CLIs n' such are nice to begin with, most of the time they get in the way if you need to customize it to another build tool. For example, when Famo.us first came out, it was entirely based around their CLI, which made any real world use a royal pain.

Will Ember 2.0 remain easy to pull in to a custom build system, etc. without the CLI?

@wycats
Member
wycats commented Nov 3, 2014

@Pradeek In today's controllers, there are usually several things going on:

  1. A few properties that are meant to persist across navigations and may be attached to query parameters
  2. Computed properties that convert those properties into something suitable for display
  3. Handling events produced by the top-level template, and manipulating those properties

Looking at a lot of apps (including our own) and listening to people ask us questions about the role of the controller, it is clear that the last two responsibilities above have equivalents on components. Letting you think of the top-level context as a component doesn't harm the architecture at all, but removes an unnecessary component.

As for the second bullet, we agree that there is a need for a place to store a small number of properties that persist across navigations, similar to the "session" concept in server-side frameworks, but that requirements has grown into a vestigial top-level role in the system that we think makes it ambiguous where to put common functionality.

In short, the extra concept simply wasn't paying its way. After answering "what exactly should go in the component" hundreds of times to new developers at trainings, clients, attendees at hack nights and more, we realized that everyone would be better off by moving the responsibilities into objects with more clearly designed responsibilities.

Nothing is stopping you from breaking out functionality or logic that you don't think really belongs associated with the view layer into a separate object, and we definitely encourage experienced developers to decouple their code!

@taras
taras commented Nov 3, 2014

@Pradeek @James1x0 the difference between current route controllers & future component is largely ergonomics.

Technically speaking both are very similar. Currently, when a user enters a route the router instantiates a controller and binds it to a template. An virtual view is created which handles events that are triggered in the DOM. So, we have a route + controller + template + view, but all of these have separate classes with properties that need to be wired together by the template.

With the new approach, you still have route but controller, template & view are unified into 1 component. This makes it a lot easier to keep track of all of the code that is related to one route. You can actually use a component for a route today, but it requires a bit of extra wiring and it's not as well organized as it will be in the future.

@wycats
Member
wycats commented Nov 3, 2014

@nybblr we're going to focus on making the CLI the best possible experience, but there are two decent escape valves:

  • The Ember framework itself is decoupled from the file system; it looks for modules through an object called the "resolver". Ember 2.0 applications will need to use some JavaScript module system, but an AMD-based or CJS-based resolver will work without any changes to the framework itself.
  • The division of responsibilities between Ember CLI and other build systems is pretty clear: you can have your build system invoke Ember CLI commands as part of the build process. At @tildeio, our Ember app is a full Ember CLI app, but it's integrated with our Rails development server and request/response lifecycle so we can run the two together seamlessly.

I expect people to build integrations along both of these lines in the months ahead.

@lrdiv
lrdiv commented Nov 3, 2014

👍 👍

@opsb
opsb commented Nov 3, 2014

This looks very good! Couple of questions about actions:

  1. With routing directly to components, will events generated in components be able to bubble up through parent components?
  2. It looks like it will be possible to return a promise from actions, is this the plan?
@searls
searls commented Nov 3, 2014

@nybblr a vain and jealous part of me (as maintainer of @linemanjs) is disappointed that moving forward, there will be an expected 1:1 coupling between "ember apps" and "the build tool for ember apps", but I think this is absolutely the right move.

We wrote Lineman because it gave us the opportunity to package a massive number of build configurations when all we set in stone were a handful of important conventions (e.g. javascript goes here, fonts go there). We intentionally only focused on things at the file-organization layer, because we wanted to stay out of any framework churn (and there's been plenty of it in the two years since), making it really easy to switch between projects.

What attracted me to Ember, and why I loved @wycats' Railsconf 2014 keynote, is that the same embrace of a handful of carefully-planned conventions provide a tremendous amount of productivity to people writing Ember apps. By just following those, you get default behavior "for free", and that lets developers focus on more important problems. In fact, it actively discourages developers from answering a myriad of meaningless questions about code organization and naming, which is sometimes just as important.

When I read @tomdale's 2.0 roadmap note, and as I've watched ember-cli pick up steam from the sidelines, I'm encouraged to believe that the project is now at a point of maturity, size, and understanding to establish conventions in both build tools and framework APIs that will play together really nicely.

Rails is the best analogy I can think of to all of this. When I install a gem targeting Ruby on Rails apps, I can expect it will work with default behavior, more-or-less without me telling it to do anything. We're already seeing the same sort of phenomenon emerge in the nascent ecosystems of ember-cli extensions, and in my opinion that's fantastic. None of this would be practical or advisable, by the way, without the careful shepherding of API changes that the team is demonstrating in this thread.

Integrating ember CLI as a first-class part of the Ember experience accomplishes things that no other front-end web framework can do. I'm really excited for Ember's future.

@Pradeek
Pradeek commented Nov 3, 2014

@wycats I agree with the thoughts behind the computed properties and event handling, but calling it a "component" seems wrong to me because the term is largely associated with reusability which might be confusing in the long term. I had always considered the controller to mask the app business logic from the UI specific ones. Now it seems to me like that extra layer of separation would be lost.

@Pradeek
Pradeek commented Nov 3, 2014

@wycats For example, calling both a drop down and my entire detail page as components does not seem very clear on what a component entails.

@bcardarella
Contributor

Would it make sense for certain components to get mutable properties by default? For example, instead of <input value={{mut name}}> the Input component could be aware that the property being passed should be mutable internally, so you only have to do <input value={{name}}>. I can't think of many situations where you would want one-way bindings for inputs.

And there seemed to be lack of consistency in how properties are defined in HTMLBars. For examples I saw both <my-thing foo="{{bar}}"> and <my-thing foo={{bar}}>. Are the quotes around the property required?

@stopachka

So excited right now! Go ember team :)

@thecodejack

Routeable Components looks like a big change. For sometime i didn't see the use of it but now clearly removes the usage of controller from component which is really a welcome move.

@opsb
opsb commented Nov 3, 2014

What will happen to the model hook now? If the router is going to assign attrs to components then there doesn't seem to be any reason to limit it to a single model. With query params and dynamic segments I can't see any reason why the model hook shouldn't return any number of attrs (perhaps just have an attrs hook instead of model?).

@juggy
juggy commented Nov 3, 2014

Will the "bool:true:false" syntax for classes be there still for the attribute bindings? Will we be able to use it for other attributes like style?

It would be nice to be able to use the syntax within {{}} and {{mut }} as well.

I know @wycats does not like too much logic in the templates, so can you share your view there?

@wycats
Member
wycats commented Nov 3, 2014

And there seemed to be lack of consistency in how properties are defined in HTMLBars. For examples I saw both <my-thing foo="{{bar}}"> and <my-thing foo={{bar}}>. Are the quotes around the property required?

This is actually intentional. The main point is that " means a string literal (with interpolation), while no " means passing a value directly. This is similar to today's distinction in Handlebars syntax.

There is a key difference in HTML between attributes, which are always strings, and properties, which aren't. Most developers don't have a clear mental model for this, which became obvious to me when we tried to roll out $.prop in jQuery, but the difference exists nonetheless.

React, Angular 2.0 and Ember all have to deal with this problem, and there are several different options:

  1. Ember 1.x: All properties become JavaScript properties on the component, with a whitelist of attributes (attributeBindings). That worked ok with the old component syntax {{my-video src=url isPlaying=val}}, but was already somewhat confusing for common attributes that we didn't whitelist in the framework. We also don't think this will work at all when we switch to HTML-based syntax (people will expect <my-video title={{val}}> to set the HTML attribute title)
  2. Angular 2.x original announcement: Attributes are always attributes, unless surrounded in [], so <my-video title="{{val}}"> works as expected, but <input checked="{{val}}"> will not work as expected (<input [checked]="{{val}}"> is required).
  3. React: All values are properties. If you want a string, quote the value. You are required to use the property form of attribute names (<label htmlFor=val> instead of <label for=val>, <div className=val> instead of <div class=val>, multi-word attributes like maxlength must use the camelcased form).
  4. Ember 2.0: Same as React (all values are properties, and quoting creates a string), except that we map the attribute naming in HTML to properties and we handle any quirks in the mapping between props and attributes. In the vast majority of cases, the DOM's prop->attr binding does the thing you would expect, so this helps people maintain their existing mental model (and use existing HTML code).

All of that is somewhat involved, but our major goal was to try to smooth out the attrs/props distinction if at all possible for many, many cases. So the TLDR is "write attributes as you would have before, and use the string form if you want to pass a string as opposed to a value". We weighed a lot of different usage patterns, and given the capabilities of a pre-processor, this seemed like the best path.

In general, we are trying to keep our HTML dialect very close to regular HTML (especially compared to the Angular 2.x announcement and React's approach), but are willing to make small tweaks that wouldn't work with a traditional HTML parser if it simplifies how people write templates in a way that matches the natural expectation.

@rwjblue
Member
rwjblue commented Nov 3, 2014

Will Ember 2.0 remain easy to pull in to a custom build system, etc. without the CLI?

The guides and documentation will definitely be focusing on usage with Ember CLI, but it will absolutely be straight-forward to use with whatever build tool you would like. We will continue to have builds published to the various channels (currently we use Bower, RubyGems, http://emberjs.com/builds/).

@workmanw
Contributor
workmanw commented Nov 3, 2014

I think the only thing that gives me pause is the Routeable Components. On the surface I appreciate the harmony this will bring to the API. And might be a little easier for new users to understand. But this feels like a bit of a move away from MVC. One of the greatest things about the separation between views and controllers is their life cycles.

To put a head on my concerns.

  • Persistency of temporary domain state. With the current V/C pattern it is possible for a user to navigate away and return to where they are. Keeping the controller state in tacked.
  • Separation of class hierarchy. We have quite a few really really customized views and similarly controllers. These do everything from drag/drop, mouseMove, keyUp, etc on the view side, to selection, commenting, realtime support, etc on the controller side. That's a wide range of responsibilities to get mashed on to a single class. And organizing that becomes a bit harder.
  • Separation of responsibilities. Views handling user interaction (app state). Controllers handling ajax requests (domain state). I.E. it feels weird that my mouseDown event handler is right next to my ajax server call.

TL;DR; Concerns: Blurred lines between app state and domain state w/ Routable Components.


Edit: Adding another concern:

  • Caching of server query results. With the current V/C pattern, it's possible for users to jump between a list of items, a full detail view for an individual item when they do not share a route resource hierarchy. The list controller can keep a cached copy of that query results as to not add a delay an impact UX.
@mgenev
mgenev commented Nov 3, 2014

I can't say I understand well what's happening with controllers / components. What is to gain with phasing out controllers and how are we going to handle the arrayController - itemController relationship?

@sandstrom

I like this roadmap!

The idea of 'Stability without Stagnation' is great. You've stricken a good balance so far, and it's important to stay on top of changes in html/js/browsers to remain relevant as a framework. The future is bright for Ember! 😄

I have some gripes with routable components, mostly with the naming (apart from naming, the changes sound reasonable, so no immediate objections there).

In my mind a component is a small, reusable piece of code. Some are reusable to the point where other projects could use them, and other components are reusable within a project.

I'd argue that a 'routable component' is remote from what most people associate with a component, to the point where it would be better if it's called something else.

Perhaps there another name (which doesn't allude to reusability) that would be a better fit for this route-driven component. It could be identical to a component, but with a name that makes its role less confusing.

Also, will controllers remain (as item-controllers) and virtual/generated controllers for these new, routable components? Although I assume they remain, perhaps that could be clarified in the section on routable components.

@mitchlloyd

@mgenev Using an array controller with an itemController behaves a lot like creating a component inside of an {{#each}} block. I would imagine that the itemController concept could be replaced with a component, but I would be interested in hearing a core team member weigh in on itemController.

I'm with @pradeek as far as being concerned about naming and vocabulary when losing "controller". I think just as we have different names for different types objects in OO programming we're going to need to develop names for the "small, reusable components" and the "domain-specific, application components".

I'm also curious about the life-cycle of routable components. I like being able to click a checkbox in my UI, navigate away and then return to see that checkbox still checked. I'll be interested to see how moving this application state to routes changes things.

@kumavis
kumavis commented Nov 3, 2014

Re: Routeable Components

Does this mean we will put our {{outlet}} tags in our component's templates?

Currently components only emit actions that have been specified. Does this mean we need to name all actions we expect to bubble through our routable components?

Here is a contrived example as I'm not sure what it would actually look like

<video-section playingBegins={{action "videoStart"}} videoSelected={{action "videoChanged"}}>
  <video-player playing={{action "playingBegins"}}></video-player>
  <video-list selected={{action "videoSelected"}}></video-player>
</video-section>
@wycats
Member
wycats commented Nov 3, 2014

The comments about "component" connoting "reusable" are very good. @tomdale had said something similar to me (and at the face to face), but it was hard to know without general feedback, so this is very good.

Thanks all!

@gtrak
gtrak commented Nov 3, 2014

Composable components! Exciting news for a clojurist trapped in ember-land. Overall, this looks really coherent and addresses many of my gripes with 1.x.

@alexblom
alexblom commented Nov 3, 2014

Way to go. Very excited for Block Params. 👍

@mgenev
mgenev commented Nov 3, 2014

"Currently components only emit actions that have been specified. Does this mean we need to name all actions we expect to bubble through our routable components?"

@kumavis I wondered the same about that. It would be highly inconvenient.

Overall, I don't see how a component can replace controllers cleanly and maintain the ease of use. I'm of course open to persuasion by the smart guys on the core team, but I'd need to see all the possible usages addressed like

-arrayControllers
-itemControllers
-queryParams
-sorting
-filtering
-actions
etc.

to me as well, a component is something that should be reusable across apps. A controller has many other uses.

@opsb
opsb commented Nov 3, 2014

@wycats historically one of the main differences between controller/views and components was that a controller could only receive a single model from the routing layer/render helper whereas components may have several parameters. This always felt a bit awkward, being able to map multiple properties from the routing layer to the component would be great. Is this the plan? i.e. will the model hook be altered to expect multiple properties to be returned(to be mapped to the component's attrs) or will there still be a notion of a specific model?

@domenic
domenic commented Nov 3, 2014

We do not plan to remove support for existing templating syntax (or no-longer-necessary helpers like bind-attr) in Ember 2.0.

We have no plans to remove support for the old component syntax in Ember 2.0.

We have no plans to remove support for the {{each}} and {{with}} special forms in Ember 2.0.

I can understand the desire not to make people rewrite, but doesn't this hurt the ability of a new developer to come on to an Ember project and immediately be productive in the conventions that are shared across Ember users? Now they'll have to learn whether the team they're on uses {{my-component}} or , or {{bind-attr}} vs. attr={{value}}.

Especially since these are mechanical upgrades (at least if you insert mut in the appropriate places), it would make more sense to me to deprecate them in 1.x and remove them in 2.0, so that 2.0 codebases are consistent and easy to understand.

Beginning in Ember 1.11, we will support an HTML-based syntax for components

Will these be (subclasses of) HTMLElement, or will they be more HTMLUnknownElement? If I do document.body.innerHTML = <my-component>stuff</my-component>, will that be a fully functional component, or do I need to tell Ember to re-parse and "activate"? Basically, are you guys using custom elements or not.

@knownasilya
Contributor

Totally with @domenic about removing some of the old syntax. As previously stated, it would create many branches in best practices around those areas. We use Ember in our team because we can open a project and know what's going on. The more conventions we need to document the harder it becomes to keep applications consistent between developers, and from one application to another. This kind of reminds me of how Angular 1.x handled modules, there was like 4 ways to do it, and no one is sure which is best (plus the undocumented caveats).

@kumavis
kumavis commented Nov 3, 2014

@domenic One reason for keeping the old syntax around is (perhaps) to allow 2.x apps to consume 3rd party 1.x widgets. Its one thing to move your own code base, but it can be blocking if you can no longer consume some of your deps

@rwjblue
Member
rwjblue commented Nov 3, 2014

@opsb

Being able to map multiple properties from the routing layer to the component would be great. Is this the plan?

Yes, the idea is that there will be an API (similar in concept to setupController) that will provide the attrs hash to the routable component. The output of this hook (don't think we have settled on the exact name) would be run through RSVP.hash so that you can have any number of promises resolved and passed into the component.

@phpnode
phpnode commented Nov 3, 2014

@domenic understand your argument but this is exactly the objection people are having with angular 2.0. Yes it's conceptually cleaner to remove this older syntax, but it leaves the existing community high and dry. If the cost of supporting the older syntax is low, it's much more pragmatic to deprecate in 2.0 and remove in 3.0. Docs can emphasise the newer APIs.

@tim-evans

@wycats @tomdale There has been talk by @trek of a "presenter" layer. (In regards to routable components)

@mixonic
Member
mixonic commented Nov 3, 2014

@domenic

Will these be (subclasses of) HTMLElement, or will they be more HTMLUnknownElement? If I do document.body.innerHTML = stuff, will that be a fully functional component, or do I need to tell Ember to re-parse and "activate"? Basically, are you guys using custom elements or not.

These will be components. {{#x-foo}}{{bar}}{{/x-foo}} and <x-foo>{{bar}}</x-foo> are basically equivalent, both referencing the App.XFooComponent global or app/components/x-foo.js (in Ember-CLI) class. We're not thinking about how to support components on the raw DOM as part of 2.0, but it is an interesting avenue to consider. Routable components and this syntax get us closer to having a decent API for part-of-page Ember usage and migration to a SPA, but again this is only an idea.

@rwjblue
Member
rwjblue commented Nov 3, 2014

@domenic

I can understand the desire not to make people rewrite, but doesn't this hurt the ability of a new developer to come on to an Ember project and immediately be productive in the conventions that are shared across Ember users? Now they'll have to learn whether the team they're on uses {{my-component}} or , or {{bind-attr}} vs. attr={{value}}.

The older forms will cause a deprecation warning, and I plan to make ember test (from Ember CLI) to fail test runs upon hitting a deprecation warning.

Removing support in 2.0 for some items would basically mean that folks simply cannot upgrade. It is extremely important to us to ensure that upgrading does not require so much effort as to be untenable .

@knownasilya
Contributor

@rwjblue

Removing support in 2.0 for some items would basically mean that folks simply cannot upgrade.

Wouldn't bringing in these features incrementally under feature flags make this an incremental transition so that folks can upgrade slowly, making the removal of the old APIs much less painful?

Sure someone can go from 1.8 to 2.0, but that is their choice. Going from 1.8 --> 1.9 --> 1.10, etc.. will make it least painful and will allow for those folks to upgrade since they'll only have to handle a handful of changes.

Otherwise, it would be important to document those things as deprecated, move them to the bottom of the list and grey them out (in the docs).. 😄

@stevehanson

I'm concerned about this statement:

While globals-based apps will continue to work in 2.0, we may introduce new features that rely on either Ember CLI or ES6 modules. You should begin moving your app to Ember CLI as soon as possible.

I have been using Ember Rails to build an admin interface as part of a Rails engine and have been very happy with it. I would prefer that apps that use my engine not have to install Ember CLI to be able to work with it.

Also, wouldn't requiring that Ember be used with Ember CLI mean that Ember could no longer be added to existing apps that have their own build processes without disrupting them?

I love Ember CLI, and I think it's an incredible tool for most front-end apps. I am just concerned that making it required to develop with Ember might disrupt a lot of workflows.

Overall though, really excited about Ember 2.0! 👍

@Panman8201

Few comments/questions:

Block Parameters
  • Why use | pipes? Seems confusing to me, adds bloat
  • Won't there continue to be a need for {{each}}? Without requires users to make a Component just to loop..
  • UPDATE: Comment here: #3
More Consistent Handlebars Scope

I actually like the context-switching {{each}} loops. Shortened the key names needed; {{firstname}} instead of {{person.firstname}} The implementation seemed logical and understandable to me. And in the Transition part, do you mean the "named-parameter form" as {{#each person in people}}?

One-Way Bindings by Default

Although the reasoning/need for one-way bindings is good, I'm not sure changing how two brackets works {{foo}} is the right way to go about it. What about making a one bracket option {foo}? One = one-way, two = two-way. Then highly publicize that one is the most common need for most things. At least don't use mut for the keyword..

Separated Component Parameters

I've always understood it as attribute == property. Although I'm fine with the change to attrs, I think it'll add one more level of complexity. (Increasing the learning curve for Ember)

Routes drive components, instead of controller + template

I think you mean "instead of controller + view + template".?. Speaking of which, what will happen to Views?

Improving Actions

What about the promise-aware/stateful actions in "Better Actions" by matchy? I'd like to see that as well. Also, what is the conceptual difference between actions and events (besides actions == JavaScript and events == DOM)? Most developers know .on/off() from the jQuery days..

Services (and needs:[] changes)

No mention of Services? Maybe that's already coming pre-2.0? One thing I really liked about Tom's proposal was the alias helpers instead of the needs:[] option. Eg: fooBar: Ember.controller('foo-bar') It's just weird that Controllers have a needs:[] but Routes and other aspects of Ember don't. UPDATE: New injections here: emberjs/ember.js#5162

Buffered Changes

I think there is enough need and a common pattern for the "buffered proxy" addon to be included into Ember. I'd really like to be able to "delay" bindings of Ember Data records until they are successfully saved.

I also have more "wishlist" items but I think these are at the top of my list. Thanks! http://discuss.emberjs.com/t/ember-wishlist/6605

@AdamFerguson

Since controllers are going away, does this mean that the needs api will not be available within components? Also, will components not be long lived representations of application state?

For better or worse, I've worked on projects where controllers acted as almost a data store where a controller would be the primary means of accessing a particular piece of application state. Knowing more about Ember now, I know it's better to to have routes pass the state to particular controllers instead of relying on needs. Still, it can be very convenient. If controllers go away, I think it would be great if service objects had an API to replicate the functionality provided by needs. Perhaps components could specify that they need a particular service object which could have it's state set at the route level?

@taras
taras commented Nov 3, 2014

@stevehanson your use case is becoming increasingly less common. There are many many benefits to using Ember app as a compiled dependency in Rails projects instead of using globals with sprockets. In the long run, it might be easier to ask people to install ember-cli than asking them to work on an Ember project that uses globals.

@ebryn
Member
ebryn commented Nov 3, 2014

@AdamFerguson services will become an important piece of that story: http://discuss.emberjs.com/t/services-a-rumination-on-introducing-a-new-role-into-the-ember-programming-model/4947

re: long lived state, routes will be taking over that responsibility from controllers

@cibernox
Contributor
cibernox commented Nov 3, 2014

This this uber-great!

Specially I like the react-inspired ideas. From my limited experience, react is great, flux is not. This is for me like keeping the good things (virtual DOM + one way binding) of react avoiding the cumbersome callbacks and shared state in the root is like cherry picking "The good parts™".

@chadwithuhc

I am on the same page as @Panman8201.
What is the purpose of the pipes in {{#each people as |person|}}?

@rwjblue
Member
rwjblue commented Nov 3, 2014

@knownasilya

Wouldn't bringing in these features incrementally under feature flags make this an incremental transition so that folks can upgrade slowly, making the removal of the old APIs much less painful?

Yep, that is entirely the point of the gradual process. The older 1.x compat features will be available but they will trigger a deprecation warning. This solves the concern stated by @domenic that various code-bases would be completely different (some using {{bind-attr foo=bar}} and others using foo={{bar}}) by making it clearly the "wrong path" with the deprecations.

Once 2.0 lands and has shaken out over a number of releases, we can start thinking about removing long deprecated functionality. We will not run out of version numbers. 😉

@tim-evans

I'm with @chadwithuhc and @Panman8201 - the block syntax seems wobbly to me. For me personally, it doesn't feel right. Any other syntax alternatives? I'm all for the idea, by the way.

@stevehanson

@taras - Thanks for the reply!

I submit that there may be some benefits to not using globals, but I fail to see why Ember CLI is required to achieve those benefits. It seems like a softer requirement, like requiring ES6 modules be used, or requiring that components be hooked up to the Ember app explicitly via some resolver hooks would still allow us to accomplish what we want without requiring the full blown CLI.

Why limit Ember to not be a candidate for my use-case (and likely many other use-cases) when we don't have to?

@rwjblue
Member
rwjblue commented Nov 3, 2014

@stevehanson:

While globals-based apps will continue to work in 2.0, we may introduce new features that rely on either Ember CLI or ES6 modules.

I am just concerned that making it required to develop with Ember might disrupt a lot of workflows.

It will absolutely NOT be required to use Ember CLI when you are developing an Ember app, but it will be our primary focus for documentation and guides.

As the RFC mentions, since we can guarantee the build process there are some specific features that can be enabled and "just work" for those using Ember CLI.

@stevehanson

@rwjblue 👍 awesome! Great work on Ember and Ember CLI, btw!

@rwjblue
Member
rwjblue commented Nov 3, 2014

@tim-evans, @Panman8201, @chadwithuhc:

I'm with @chadwithuhc and @Panman8201 - the block syntax seems wobbly to me. For me personally, it doesn't feel right. Any other syntax alternatives? I'm all for the idea, by the way.

The point here, is that block params will be a part of Ember 2.0. Please raise your syntax specific concerns in the Block Params RFC.

@mixonic
Member
mixonic commented Nov 3, 2014

Fwiw we stared at {{#each cars as car}} and {{#each cars |car|}} with single and multiple arguments for a while. I'm pretty pleased at how easily readable the combination of the two is.

@knownasilya
Contributor

Also like the readability, and use of a character that isn't really used elsewhere. Easy to distinguish.

@tomdale
Member
tomdale commented Nov 3, 2014

@workmanw Great points, and all topics we’ve spent a lot of time discussing. We agree with the need to have somewhere to store persistent application state, and we’ve got some ideas that we think we’ll be much easier for new developers to the framework to pick up. You’ll see those fleshed out in the coming weeks in the routable components RFC.

Regarding separation of class hierarchy, a PR adding the notion of services has been merged but is not yet enabled by default pending some API polish around validation. Services are a great option for real-time support, etc. Components should handle all of the view-related stuff from before, just with better isolation—you should be able to convert a view into a component with few changes.

Regarding separation of responsibilities, I’d consider making AJAX requests from your controller a bit of an anti-pattern. This really should be the responsibility of the model layer, which is best modeled as a service. (We intend to refactor Ember Data’s store to be a service, for example.)

@mgenev We pay a lot of attention to how new users learn the framework, and the role of controllers has always been a stumbling block. This change should dramatically reduce the learning curve, something I’m sure you’ve heard people complain about when learning Ember.

Regarding item controllers, the improvements to components and the template layer means that we are able to replace many different APIs with a single abstraction: {{#each}} and components. If it’s not clear how this would work, or you think there are some cases we may have missed, please feel free to post a small example and we will attempt to translate it to idiomatic 2.0 code.

@sandstrom We agree that naming is very important. We have to balance clarity of naming with the learning curve. We want new developers to understand that a “routable component” is just like any other component, with the same syntax and semantics.

I’d argue that the high order bit of why components are important is not reusability, but isolation. Reusability is a very nice side-effect that falls out of isolation. By replacing controllers+views with components, the isolation that comes with components buys us a lot of clarity in terms of data flow, specifically from the route to the component.

If it makes the mental model easier, you may want to think about it in terms of the router dynamically writing the top-level Handlebars template for you. If the route is /users, it automatically generates the HTML <users model={{users}}></users>. If the route is /favorite-photos, it automatically generates the HTML <favorite-photos model={{favoritePhotos}}></favorite-photos>. (This is not actually what happens, of course— but I think it helps me form a mental model.)

Also, will controllers remain (as item-controllers) and virtual/generated controllers for these new, routable components? Although I assume they remain, perhaps that could be clarified in the section on routable components.

While they will still be supported through the plugin, we intended to remove Ember.Controller, Ember.ObjectController, and Ember.ArrayController from the framework, including their use as item controllers. Our hope is that you can express the same concepts using the more flexible primitives of template helpers and components. As we said to @mgenev above, please let us know of cases where it’s not obvious how you’d accomplish this and we’ll double-check our assumptions.

@kumavis, yes, you will put {{outlet}} helpers in component templates. We are also working out if it is possible to replace {{outlet}} and use the existing {{yield}} semantics.

Regarding actions and child components, yes, you will need to explicitly pass the actions down through child components. We are always looking for ways to improve ergonomics, so if this becomes annoying to people we will investigate syntactic sugar to handle this case more tersely. However, we really like the fact that in React, mutations by child components can only happen if explicitly allowed by their parent, and developers who’ve used React tell us the same thing.

@opsb, the model hook will stick around, but it will just be treated as a special attr that gets passed to the component. As we mentioned, there will also be an attrs hook on the Route that you can use to pass arbitrary data to the component; we will merge the results of attrs with the model returned from the model hook. More detail about this in the forthcoming RFC.

@domenic, In Ember 2.0, we care a lot about consuming custom elements, and this is something that has informed our design. We expect the HTMLBars engine to work seamlessly with custom elements that interoperate using properties and events.

We are still thinking about how to make Ember components themselves work as custom elements. We have some ideas, but there is still some way to go before we cross that final gulf. I suspect many of the frameworks will iterate on similar solutions (something like an HTMLElement subclass that knows enough about Ember to bootstrap its components).

With regard to keeping the old syntax around, we will be deprecating it before 2.0, and providing both console warnings and an inspector tab to make sure that people know they are on the wrong path. I do not expect new tutorials or answers on Stack Overflow to offer people suggestions that will immediately result in deprecation notices being printed.

I’d also love to know if @jandet shares your feelings about being more aggressive in removing vs. deprecating old syntax. ;)

@knownasilya There won’t be any ambiguity about which syntax is correct. Between the console logs and inspector pane, we will be loud about the fact that people are using an out-of-date API.

@kumavis, Exactly, preserving the ecosystem’s momentum is one of our highest priorities. We saw what happened with Python when it was impossible to write a library that worked in both 2.x and 3.x. We are committed to providing APIs that allow authors to distribute Ember add-ons that work in both environments for the foreseeable future.

@stevehanson, because we have been building Ember CLI in as modular a way as possible, we fully expect the community to build integrations into other build pipelines. We would love to see first-class support for integrating Broccoli/Ember CLI into Rails and other build pipelines. We think it’s eminently possible to do so, because we’ve designed the Ember CLI architecture with this use case in mind.

@AdamFerguson, needs is being replaced with injected properties, which provides a much more flexible primitive for accomplishing the same goal, and is usable in components.

We are working on an API for long-lived application state, as mentioned above.

@cibernox Yes, agreed. We’ve been really excited by the ideas in React for some time, but continue to find Flux behind the state of the art when it comes to managing overall application architecture.

Phew! Thanks for all of the great feedback. Now I’m gonna go grab some lunch with @wycats (who also helped write this response).

@thelinuxlich thelinuxlich referenced this pull request in vuejs/Discussion Nov 3, 2014
Open

Not a question, just a positive thought #87

@chrism
chrism commented Nov 3, 2014

This all looks really great!

Like a couple of others have already mentioned the controller transition looks like it could be a bit daunting, but I think the rationale makes sense - it will just be a case of understanding how to allow for the occasional need to maintain state will work in practice.

Another minor point/question is will this new each syntax allow for an each_with_index equivalent - thats one of the few times I've needed to dig into a View. As a rubyist the block syntax looks fine to me.

But really I just wanted to say congratulations to you guys - as a very happy user of Ember this is so great to see. Thanks for all your hard work.

@cibernox
Contributor
cibernox commented Nov 3, 2014

I think that in the original RFC about the new block syntax one argument about having the piped delimiting the parameters being yielded to the block is that it allows to decompose objects.

{{#each object as |key, value|}}
  {{key}} is {{value}}
{{/each}}

(maybe without the comma in the middle, I don't remember the final decision)

@swastik
swastik commented Nov 3, 2014

Excellent! 👍

@pwfisher
pwfisher commented Nov 3, 2014

Really like the improvements in consistency and simplicity (e.g. consistent handlebars scope, explicit two-way bindings).

I'm a little worried about the filesystem changes implied by this roadmap - which do not seem simple and consistent.

  1. Will single-node components still require empty template files?

Routeable Components should be placed in a "pod" naming convention. For example, the component for the blog-post route would be app/blog-post/component.js.

  1. Is this part of a larger change to the filesystem structure? This seems incompatible with the current approach of grouping files by type (e.g. in ember app kit).
@stefanpenner
Member

Is this part of a larger change to the filesystem structure? This seems incompatible with the current approach of grouping files by type (e.g. in ember app kit).

It layers on top of the existing file-system scheme used by apps built with ember-cli or EAK.

@workmanw
Contributor
workmanw commented Nov 3, 2014

@tomdale Thank you for taking the time to reply to each of our concerns individually.

With regards to the AJAX comment, unfortunately we find that Ember-data doesn't always live up to our needs. Things like paging (infinite scroll type), bulk operations, cross entity transactions, etc, aren't always easy with Ember-data. We often have to default back to making AJAX calls. I could do this AJAX in a global controller (service), in an adapter that is called directly, or wherever.

My point wasn't so much that I'm calling AJAX in my controller, it was that this the very same class that handles view life-cycle, DOM events, etc, is becoming the same class that contains my models and other pieces of domain state. Ultimately coupling the two together; once the view is destroyed, so the the guy who held the data.

We have a pretty complex app with a lot of custom views. With this RFC and other recent changes I'm just worried that focusing on simplicity and ease comes at the cost of power and flexibility. That said, I have full confidence in you guys and in the process. I'm just taking this opportunity to voice these concerns.

@tchak
Member
tchak commented Nov 3, 2014

What about .modal() in routing DSL or some other way to handle routes without url?

@samdelagarza

Ember-CLI as of last week still isn't very usable on windows because brocolli is dreadfully slow on windows. As I understand it, brocolli isn't the problem but a specific subsystem of node.

Any thoughts on attacking the problem in node before Ember-CLI becomes the norm so that we don't get a rash of "Ember isn't usable in windows" posts all over the internet?

@tomdale
Member
tomdale commented Nov 3, 2014

@samdelagarza Absolutely agree. First-class Windows support is extremely important to us, and we're working hard on it. That said, very few on the core team are Windows experts, nor do people have a ton of bandwidth. If anyone with node+Windows expertise can help out, we would greatly appreciate it: broccolijs/node-symlink-or-copy#1

@cibernox
Contributor
cibernox commented Nov 3, 2014

@samdelagarza I can give some inlight about that since in the last Ember London Hacking Nights some people was just working on it.

They managed to reduce the build time of a project from 30s to 2s, but support is not ready yet. I've been told that there is some edge cases with the way windows handles permissions that need to be addressed before releasing this.

But I would expect this to be fixed soon.

@manufaktor

Separated Component Parameters
It starts to make sense after reading the documentation for React's lifecycle callbacks and feels inline with the general proposed direction of the framework. In my experience though, anything I passed into a component (or a controller via setupController) was always more in the sense of model data than attrs but maybe this is just semantics, so maybe I was already using attrs disguised as model in current versions of ember. I was then also relying on template helpers instead of the magic behavior of ArrayController et al.

Routeable Components
So is this like a controller + view responsibility merge and navigation state get's moved to the route?

Instead of referring to model properties directly (or on this), you will refer to them as model.propName.

Wouldn't .propName be private API? Will I have to use attrs. here? Maybe this is too early but I'm already confused :)

Anyway, I agree with some of the comments that "Component" is a "reusable" thing and it feels a bit weird. Yes that mean's it's also isolated, but for me the primary association is indeed reusable. Current ember controllers are singletons, so it does feel a bit unnatural to refactor them into components, as none of them are really reusable (nor composable, same with routes).

Generally
Overall this feels like a good direction, so congrats and thanks very much to all you guys, this is good news!

@blesh
blesh commented Nov 4, 2014

I realize this is a tertiary concern, but has there been much discussion around how to deal with streaming data (i.e. Sockets or SSE versus REST/HTTP) in Ember going forward? Is Ember-Data going to evolve to better suit this scenario? Is there going to be more guidance from the framework as to where and how to set up and tear down subscriptions to streams of data?

Ember-Data wasn't the right solution for us (Netflix) at the time we started development, and even trying to mirror the Model/Adapter/Store model seemed like a square-peg/round-hole problem. In the end, it's working out nicely, but the semantics around the solution and the placement of certain pieces of metadata around setting up and tearing down subscriptions weren't exactly straight forward (do I put it in the Model? the Controller? etc.)

@ebryn provided us with a lot of good guidance, but without his help it would have been very hard to decide how to piece it together. Even after he left that architecture has evolved considerably (moving some of the socket and aggregation stuff off to a Worker, etc).

EDIT: To be fair, this particular issue is something that no framework I can think of really provides a lot of guidance around. Ember at least has some strong concepts around things like "deactivating" a route, which is a boon for this scenario.

@opsb
opsb commented Nov 4, 2014

Having thought about routable components a while today I have to agree with other people here that it does feel a bit awkward, especially when you think of components from the point of view of their original inspiration, web-components.

It feels like the route objects should contain the state for that route (rather than the associated controller as it is now), these would be the long lived objects and they'd contain only callbacks, properties and actions (nothing view related, this should be handled by components in the route's template).

This simplification also makes sense when you think about the query-params issue (which now work from a practical point of view but have always seemed a little strange being bound to the controller rather than the route).

As an example

App.BlogsRoute = Ember.Route.extend({
    model: null,
    sortBy: null,
    queryParams: ['sortBy'],
    sortedBlogs: Ember.computed.sort('blogs', 'sortBy'),

    loadModel: function(params){
        this.model = this.store.find('blog'); 
        return this.model; // route in loading state until promise is resolved
    }.on("enterRoute"), // replaces existing route callbacks

    actions: {
        addBlog(name){
            this.store.createRecord('blog', {name: name});
        }
    }
});
@rwjblue
Member
rwjblue commented Nov 4, 2014

@manufaktor:

Instead of referring to model properties directly (or on this), you will refer to them as model.propName.
Wouldn't .propName be private API? Will I have to use attrs. here? Maybe this is too early but I'm already confused :)

Since this.attrs.model is the most thing you will be likely using the most, this.model will be an alias to this.attrs.model.

@hannahhoward

This is not so much a comment about direction as about tone. The first two pages of this document feel like a long subtle dig at the fact that AngularJS 2.0 is a major rewrite from the ground-up that makes for a hard migration path. I love both frameworks-- I write Angular code professionally and Ember code in my free time. They both have their strengths and weakness and the fact that many of the Ember 2.0 features are things that bring it to parity with Angular 1.0 suggests you guys see some of the Angular's strengths. I guess my feeling is, given that Ember is borrowing heavily from Angular for 2.0, why the long passage implying that Angular is screwing the community with 2.0, and this is why Ember is better? Angular 2.0 borrows heavily from the concepts you guys pioneered -- using ES6, having a data layer, etc-- why not just be flattered and focus on what will make your product great rather than taking pot shots at the other guys? Maybe theirs is a complete rewrite cause they were so far behind on certain key features and couldn't do a smooth transition path. All in all, I'd just like to see Ember focus on delivering new features that patch its weaknesses and let other frameworks alone to worry about their challenges.

@tomdale
Member
tomdale commented Nov 4, 2014

@hannahhoward First, I'm sorry that we came off as getting in a dig at Angular. I know that the timing around this seems suspicious, but I'll give my word that everything above has been planned at least 3-4 months in advance.

We had planned to announce this after our most recent face-to-face, which has been scheduled for two months, so the announcement syncing up with ng-europe was coincidental.

We think it's important to articulate our philosophy clearly since people are making multi-year bets on their technology stack. Many, many people chose Angular because they thought the Google name meant stability, which, for better or worse, did not end up coming true. We wanted to make sure that people understood exactly what they could expect from us in the future.

In the end, I wanted to communicate the dedication of the Ember community to stability. I am unsure how to provide a clear, unambiguous guarantee to our users around stability without readers inevitably comparing us to Angular, given they're the 800lb gorilla in the room and coincidentally announced their 2.0 last week.

I'll reiterate what I said on Twitter today: I may be vocal in my criticisms, but we've got nothing but serious respect for the AngularJS and React teams (as I tried to make clear in our Learning from the Community section). Competition is wonderful, and I'm glad to have both these teams challenging us to be better.

@Dave-Choi

@hannahhoward As more of an outsider, I'll back up @rwjblue and @tomdale. There was a lot of community backlash at the Angular 2.0 announcement, but if you push that out of your mind, this document just reads like what it is: Responsible ownership by people who use their own products.

As people who use their own products, they're invested and feel the pain of breaking changes, and incur the costs of having to rewrite applications, so it's just in their best interests to keep that pain to a minimum. That means a lot of work put into planning and documentation, like the excellent Ember Data transition doc, and the Ember blog. These aren't new attitudes or reactive PR maneuvers. It's just how the Ember team operates.

btw, thanks, everybody.

@hannahhoward

Tom, thanks for your direct and heartfelt reply. I trust given what you and Robert said that you didn't mean to make an anti-Angular 2.0 statement and just happened on some bad coincidental timing. I really appreciate your feedback and ultimately I really happy to hear Ember is committed to stability. In general, I agree, competition is healthy. My anxiety comes the fact I am one of those programmers having to make that decision both for professional coding and personal coding, and ultimately none of the bets really feel safe. Right now our six person dev shop has a lot more stress than a year ago when we were solidly relying on Rails, because nothing feels certain in the JS SPA ecosystem. If you're interested, my anxiety about Angular is exactly that 2.0 is a total rewrite and my company has discovered 1.0 has all kinds of warts. Simultaneously, honestly my anxiety about Ember is that it feels like there maybe isn't enough person power to keep it moving -- HTMLBars not being fully delivered this far down the road feels concerning -- even though I know the early hyping was truly an innocent mistake. And, it feels like the ecosystem for Angular is much fuller, though I guess that will change in a big way with 2.0. Anyway, hope that illuminates what it feels like for the everyday programmer -- and in fact, the fact that you recognize how difficult and uncertain these decisions are makes the whole stability focus feel very reassuring.

@samdelagarza

Fantastic!!!

Sam

On Nov 3, 2014, at 5:16 PM, Miguel Camba notifications@github.com wrote:

@samdelagarza I can give some inlight about that since in the last Ember London Hacking Nights some people was just working on it.

They managed to reduce the build time of a project from 30s to 2s, but support is not ready yet. I've been told that there is some edge cases with the way windows handles permissions that need to be addressed before releasing this.

But I would expect this to be fixed soon.


Reply to this email directly or view it on GitHub.

@jerel
jerel commented Nov 4, 2014

First: Thank you! I'm giddy about these changes. I see a number of minor pain points being resolved in this RFC.

Routable Components
I support the move to routable components as I have already found a tendency to use components heavily and making them routable makes an obvious and simple Ember Way™ to unite on. I'd just like to bring up the topic of interfacing with external DOM libraries such as Leaflet (web maps), d3, three.js, etc that take control of a section of the DOM. Ideally (imo) a parent component could handle library setup and child components could display/remove data via that library's methods without touching the DOM themselves. Has some thought been given to such scenarios? I didn't find it very intuitive to do this in current Ember but it was possible using a combination of controllers and views.

@ulisesrmzroche

Fiesta! 🎉

@Pradeek
Pradeek commented Nov 4, 2014

I’d argue that the high order bit of why components are important is not reusability, but isolation. Reusability is a very nice side-effect that falls out of isolation. By replacing controllers+views with components, the isolation that comes with components buys us a lot of clarity in terms of data flow, specifically from the route to the component.

@tomdale My only concern is that controllers represented a place to put common business logic for one action which had multiple views. Views could contain UI specific computed properties / validation and controllers had the business logic specific computed properties / validation set up. Multiple views/UIs could reuse the controller for the same action. Would be more interested in seeing the ideas fleshed out in a separate RFC though, we could keep the discussion with proper examples going over there.

@blessenm
blessenm commented Nov 4, 2014

I see some of the old api's will be supported in 2.0 and some will be supported via an addon. Why not make all the code that maintains compatibility as an addon? Is there any work done for project svelte in 2.0?

@trabus
trabus commented Nov 4, 2014

I hope this doesn't come off as naive, but regarding the {{mut foo}} syntax, would it make more sense to move the way the binding is setup to the component instead?

The example of <my-video src={{movie.url}} paused={{mut controller.isPaused}}> </my-video> illustrates to me that the src property's mutability in this example should be up to the component, and not the template in which it is implemented. As the designer of the component, I would have understanding of side effects a mutable property would create, and thus by defining my interface with that in mind, I would define the src attribute as immutable. Allowing the consumer of the component to define mutability of an attribute could result in unintended consequences and frustration for the consumer.

This seems like it would go against the next item in the list, the separated component parameters, however, attributes could still be defined on the component, but still be accessible through a hash if that is desired. Maybe something like Ember Data attributes, where we define a type, which would give us built in typechecking for our incoming params. We could also define whether the attribute is mutable or not, based on the way we define the attribute. The following is just a rough example:

export default Component.extend({
  /* Public API */
  src:  Ember.attr('string'), // default, one way binding, enforced type
  title: Ember.attr.mutable('string'), // two-way binding, enforced type
  paused: Ember.attr.mutable(), // two-way no enforced type


  /* Internal */
  scrubber: null
})

This would give us more or less the same thing, but with more control from the api, and less chance for misuse of a distributed component.

Anyhow, just a rough idea, I thought it might be worth sharing. The concept of oneway bindings by default definitely appeals to me, but I'm not sure if the template feels like the right place to define when something should be two-way bound.

Edit: After hearing some more about the reasoning, I was missing the point of why it goes into the template rather than the component. Putting it into the template makes the binding type explicit and clear to anyone reading the code. It removes any chance of confusion over whether a binding is mutable or not at the point of implementation, where you have knowledge of the data going into the component. This reduces the need to be defensive with your attributes.

@sergiotapia

Really excited that you guys are backing Ember CLI. I just used it yesterday and it works like a charm, really easy to get new people interested in Ember without handling any of the ugly specifics at first.

@ulisesrmzroche

I think Ember CLI should actually be on the main site, it's really that great. I wanted to ask ya'll what's up with Ember.Select, is that staying with us in 2.0?

edit: Ah, it says ember cli is going to become an integral part of Ember. nice!

@MiguelMadero

@mgenev @wycats @Pradeek @sandstrom @mitchlloyd re: reusable components. I've been approaching components lately as a type of object that provides a nice encapsulation and clean interface (set properties, sends actions), the re-use was always a secondary goal. That say it's important to distinguish between a domain specific component and a general purpose component. For the first category encapsulation is more important than re-use, even though the latter is possible, for the second category, re-use is just as important.

@MiguelMadero

I’d consider making AJAX requests from your controller a bit of an anti-pattern. This really should be the responsibility of the model layer, which is best modeled as a service. (We intend to refactor Ember Data’s store to be a service, for example.)

@tomdale how do you feel about loading data from components? not directly doing an ajax call, but something like dataAccessService.loadStuff().then.... I've heard mixed opinions in the past about this one.

@shunchu
shunchu commented Nov 4, 2014

It's so refreshing to get a clear direction on where things are going and what the upgrade paths are. Thank you guys for being considerate of the developers who use your tools to ship their products.

TL;DR

  1. Make it easy for newcomers to on-board; if you are committing to Ember-CLI, make it really clear in the docs; heck, strongly recommend it!
  2. Ember-CLI has many advantages that Ember-Rails currently does not have, namely community-build addons. If Ember-Rails won't be upgraded to include Broccoli/Ember-CLI in the near term, make this distinction clear in the docs ==> Pros/Cons of using Ember-CLI vs Ember-Rails.
  3. If investing in Ember-Rails, make it more Ember-CLI-friendly so that developers can more readily take advantage of community addons (if for nothing else).

Thoughts

@tomdale, in your response to @stevehanson's concerns on Ember-Rails/Ember-CLI, will Ember-Rails development stay on-pace with efforts on Ember-CLI? I'm relatively new to the ecosystem and have found it frustrating to get a straight answer on how to best integrate Ember with an existing Rails project. I started out with Ember-Rails only to find that the community is moving towards the "Ember-CLI way" of doing things... but not before I ran into Ember App Kit and only to learn that it was being deprecated in favor of Ember-CLI!!

Unless Ember-Rails will be upgraded to take advantage of Broccoli and Ember-CLI soon and stay on par with Ember-CLI, I personally think the advantages of Ember-CLI are simply too great to ignore. I wish I hadn't wasted 2 weeks in Ember-Rails only to find out that all the cool toys and addons like ember-cli-bootstrap (and more) are more easily obtained if the project was on Ember-CLI. And having npm and bower to manage dependencies and all the behind-the scenes stuff is just too awesome.

For the record, I eventually used Ember-CLI-Rails as the base to get my Ember project working with Rails. But there's still a ton of work to do migrating things over to the Ember-CLI way.

@wycats
Member
wycats commented Nov 4, 2014

will Ember-Rails development stay on-pace with efforts on Ember-CLI?

A lot of Ember community members who use Rails at this point have setups that integrate the Rails workflow with Ember CLI. I expect to see Ember Rails evolve towards a tool that integrates a Rails app with Ember CLI, rather than something that tries to duplicate its functionality.

At least for my apps, this is working pretty well. We just need to extract what everyone is doing into a Rails plugin so it can be used conventionally.

@wycats
Member
wycats commented Nov 4, 2014

@tomdale how do you feel about loading data from components? not directly doing an ajax call, but something like dataAccessService.loadStuff().then.... I've heard mixed opinions in the past about this one.

A lot of this will depend on your UI. In some cases, you want to load a bunch of data before you render anything to the screen, to avoid blank spots that "pop in" with data. In that case, it's best to load your data in the router, and take advantage of the asynchronous loading pipeline.

In other cases, you want to show something right away, and plan to incrementally load data when it is necessary, or show a smaller, contextual spinner as you load the data. In this case, I'd say you should load the data from what today we call a "controller", and what the RFC calls a "routeable component" in 2.0.

In general, I find it's best to try to keep data loading logic in your routes (when loaded as part of navigation) or in your top-level components (when loading them later).

As you said, you should always try to move the actual mechanics of the data loading into an external service, except perhaps when initially prototyping things. Unlike on the server-side, where data access tends to remain fairly stable, I find that data access patterns in web apps change all the time, so breaking out the mechanics into a separate service object can keep things sane.

@donaldpipowitch

I really like the spec the Ember team created here and kudos to your approach and transition plan.

I'm with @knownasilya and @domenic that I'd favor removing the old template syntax in HTMLBars. However in your responses you say that the the old syntax will be deprecated and that developers get warnings if they use the old syntax. Could this statement be added to the original proposal? "We do not plan to remove support for existing templating syntax (or no-longer-necessary helpers like bind-attr) in Ember 2.0." sounds more like the old syntax will get the same priority as the new one for me and not that this syntax is deprecated and will be removed in 3.0 maybe. It would be great to add this to the proposal for people who don't read the comments. I'm fine with explicit deprecation and warnings, if removing the old syntax isn't an option for 2.0.

@blesh
blesh commented Nov 4, 2014

@wycats that touches a little bit on what I was asking about earlier, but doesn't necessarily address the issue of streaming data. Which isn't simply "loading data" once, but actually creating observable streams of data that continuously update a view (or views), then tear it down when they're no longer needed.

I think it's very important that future efforts in this area provide clear guidance for where these things can be setup and torn down. What gets interesting about this problem, is some data streams might need to be setup and maintained for longer than just the life of a single view, where others are simply only for a single view. Also, the actual web socket itself is really secondary to the data stream, as a single stream of data might be aggregated from multiple socket connections, or multiple data streams may be sourced from a single socket connection. So where do those things get setup? What about reconnection logic and failures? Those are all things I had to address in our Ember app, and it had to be done with completely custom code, really. Since Ember-Data didn't seem to fit.

@wycats
Member
wycats commented Nov 4, 2014

@donaldpipowitch I think it makes sense to deprecate {{bind-attr}} as soon as the new attribute binding syntax lands. I am unsure if we will want to immediately deprecate the {{my-component}} syntax, so we don't flood people with so many deprecation warnings that there's no way they can upgrade.

We will likely phase in the deprecation warnings for {{my-component}} based upon how quickly the community updates. This is something we will absolutely keep an eye on and modulate as we go.

@wycats
Member
wycats commented Nov 4, 2014

@blesh That's definitely a different question. I'm sorry if I gave the impression that I meant my answer to be broad enough to cover both cases.

We use WebSockets in Skylight, and I'll try to write up a longer answer to your question tomorrow. I don't think Ember Data (using it or not) is necessarily so important to the specifics of your question 😄

@lfridael
lfridael commented Nov 4, 2014

I have to ask: will IE8 still be supported in 2.0?

@andruby
andruby commented Nov 4, 2014

The division of responsibilities between Ember CLI and other build systems is pretty clear: you can have your build system invoke Ember CLI commands as part of the build process. At @tildeio, our Ember app is a full Ember CLI app, but it's integrated with our Rails development server and request/response lifecycle so we can run the two together seamlessly.

@wycats we've been migrating our Rails+Ember app from ember-rails to ember-cli. Right now we are using the asset pipeline with es6_module_transpiler-rails and ember-resolver. Have you written about the solution you're using at @tildeio?

@cibernox
Contributor
cibernox commented Nov 4, 2014

@lfridael The plans are drop support for is 6 and 7, but not for ie 8.

@lessless
lessless commented Nov 4, 2014

How is that there is and there is no controller at the same time <my-video src={{movie.url}} paused={{mut controller.isPaused}}> </my-video> ?
As I understood it will be completely removed.
Also the other question that bothers me is a support of service workers. How do you plan to integrate them in the stack? Are there plans for an primitives?

@eccegordo

Two comments:

First,
I like where new template syntax is going. Yay for ruby like pipes and block syntax.
I am ambivalent about the angle brackets stuff here. Understand it is easy for people to grok. But there is something special about handlebars syntax being "different enough" to not be confused with actual valid HTML. A little bit of HTML DOM you can cut and paste and use all over the place (not just browsers, but email clients, editors, other tools, etc). But this virtual DOM HTML stuff is not the same. And the handlebars form of {{foo-component value="bar"}} is a strong hint that you are not looking at static HTML. Probably not much you can do about this. But I suspect you will see a different set of head scratching when some ask why

<foo-thing value="bar">Blah</foo-thing> 

does not work when pasted in JSBin or JSFiddle example. This is obviously a larger question in the world of components vs traditional HTML markup.

Second,
Routable components. Ugh here we go again. This is router 3.0 facelift/massive cosmetic surgery to cover up the horrible lack of documentation on how the router and resolver stuff works in actual practice. This is mudding one concept after another and I don't think clarity is ultimately achieved. I applaud the router first approach but you/we need to better explain some of it idiosyncrasies. As people have already stated, the long lived state of controllers seems to be lost now.

There are so many maddening little nuances about routers that this is what is really biting people in the ass. Take for example transition from a route to another route while passing a model vs passing just an id. The behavior is different and very confusing to the uninitiated.

Another, take common case where you want to load two models in one route, heaven forbid, you dare attempt this very common "anti-pattern". And speaking of anti-patterns, don't dare nest your routes unless you seriously know what you are doing.

I think a controller is a really easy concept to understand. But the interaction between a router and a controller (and more importantly between routes) is order of magnitude harder to grok. This is true in rails, true in ember, and true in frameworks that don't have a first class router API. Suffice to say the concept of routing and URLs is just really hard. State Machines are wickedly hard to understand if you don't think in the systematic terms that they dictate. You already see this with the browser makers (Safari and Chrome) doing their level best to obfuscate the URL and deprecate the very notion of an address bar. A bad trend IMHO.

Soooo.... what to do about it.

1.) Put some serious muscle behind documenting the router (who, what, where and why)

  • Explain the history and why URLs are important (@tomdale has done a great job of this in many talks)
  • More official screencasts that go deep. Explain how it all works. Make us think deeply about routing. Make us consider the interesting edge cases and corner cases.
  • Document the advanced use cases. Don't dumb down the documentation all in the name of "best practices". Let us peak at the wizard behind the curtain.
  • Bring to life the quirky weird low level details, stuff like App.Router.router.recognizer.names this kind of secret knowledge is far too informal. More rich guides and code examples please.
  • asynchrony, promises and automagical pausing for promises within the route hooks can be mind bendingly hard to grok. Unless you are intimately familiar with the implementation details. This kind of nuance is not well addressed in the guides. We need far more practical examples of the promises based syntax in the guides.

2.) Code examples, code examples, code examples.
It is nice to talk about best practices and patterns and blah blah blah. But clear code examples and working JSBins are a must have. Hat tip to @machty and the effort he put into documenting queryParams with JSBins. More of that please.

Speaking of JSBin, when ember CLI based examples become mainstream how are we going to share working code examples when everything (docs, blog posts, etc) is ES6ified and all documentation assumes Ember CLI. I am not sure how you technically do this but it sure would be nice if one could efficiently share Ember CLI code examples as easy as JSBin examples. I think perhaps we need a modules to globals transpiler that can take an ember cli example and convert to a JSBin. And vice versa take a globals example and convert to a workable module version suitable to drop into ember cli. Reduce that barrier to running example code that serves a useful pedagogical function.

Maybe more formal discussion about how the container works. Don't hide from this implementation detail. Put it out there for everyone to see. To my point about router documentation point above.

Anyway, Ember 2.0 sounds great. Appreciate the fact that you are taking the measured and incremental approach.

@lfridael
lfridael commented Nov 4, 2014

@eccegordo It seems to me that Routeable Components might very well bring simplifications that address (pun intended) some of the complexity with routing, obviating the need for in-depth documentation to begin with.

But I do have to say I disagree with your suggestion to expose implementation details. At least not in the official docs, as this gives newcomers the wrong idea of what the best practices are. Case in point: Views. The current guides do not reflect that Views are basically superseded by Components and are now considered to be an implementation detail. (Correct me if I'm wrong on this.)

@sergiolepore sergiolepore referenced this pull request in ExpressCheckout/ember-cli-ramdisk Nov 4, 2014
Open

ImDisk on windows #2

@corydperry

First of all, much appreciation for the roadmap on where Ember is going. I think it is a great help, especially for new developers like myself.

When I say new developer, I mean I literally set up my first Ember app just last night. I am just now going through the basics of learning Ember and what I can ultimately do with it. With that said, what does the roadmap look like for someone like me who is completely brand new to Ember?

The app I build right now, over the next month or two, using 1.8..... what is the ideal transition to 2.0? Would I be writing code now that would need to be refactored in a couple of months?

@corydperry

@knownasilya Nice! Exactly what I was looking for. Thanks!

@aceofspades

The Routable Components section states "In current versions of Ember, when a route is entered, it builds a controller...". It may be an important distinction in the context that as singletons, controllers are not built, but rather looked up.

@MajorBreakfast MajorBreakfast referenced this pull request Dec 9, 2014
Merged

RFC: Block params #3

@adamstac
adamstac commented Dec 9, 2014

For anyone catching up with this thread*, we had a conversation with @tomdale and @wycats on The Changelog about this -- http://thechangelog.com/131/

*Sorry to spam, but I thought a mention here would serve the community well.

@opichals

What are the thoughts about async observers with the use of Object.observe in mind and Ember evolution?

@stefanpenner
Member

What are the thoughts about async observers with the use of Object.observe in mind and Ember evolution?

We will do this at some point, it likely deserves its own RFC

@mgenev
mgenev commented Dec 10, 2014

Here's my biggest question about this migration:
Currently, I like using item controllers and item views so that I can make indexes with an array controller with an array of models which handles everything that is needed on the index level and then I make an item controller and item view which handle all computed properties which have to compute differently for each item based on each item's model, same thing applies for the actions and events.

This is very simple and easy to use and looks like this: I have an inbox route with an inbox template to which corresponds an array controller. In there I declare:

{{#each paged itemController='messages.message-list-item'}}
    {{view 'messages.inbox-list-item'}}
{{/each}}

With this simple declaration I am able to tell Ember:

  1. to process each model's computed properties individually in the controller 'messages.message-list-item'

  2. Use those individual computed properties in the 'messages.inbox-list-item' template

  3. Trigger actions from each item in the 'messages.inbox-list-item' template which get handled in the 'messages.message-list-item' and do not affect the other items in the list

  4. Handle each item's events in the 'messages.inbox-list-item' view without affecting the other items in the list

Since controllers and views are coming out in Ember 2.0. How will this look like?

@knownasilya
Contributor
{{#each paged as |page|}}
  <inbox-list-item page={{page}}>
{{/each}}

cc @mgenev

@michaelrkn

In addition to the asynchronous model hook in routes, routes will also be able to define a attrs hook, which can return additional asynchronous data that should be provided to the component.

Why not do away with the model hook entirely, and let routes pass any arbitrary data to the attrs hook, including one or more models?

@nlutterman

We have our own common language in Ember and as such which we can decide to re-define. I wouldn't get too attached to the MV*. Let's embrace the patterns/names that work for us and argue about the merits of new vs old ideas without external name preconceptions that we're already not even adhering to.

@MiguelMadero I agree, absolutely, with this. I really think that Ember 2.0 needs to use different semantics from what people already understand for established practices with regard to MV*. Even from what was established with Ember 1.*. They don't need to come up with their own words, but I would really prefer if they didn't inadvertently redefine some concepts for some people. For instance, controllers/views aren't really controllers/views, but are intended to be used together, like components, and everyone says "just use components" now, since they're rarely decoupled. Routes are sorta-kinda routes, and sorta-kinda controllers mixed together. If they would have been called different things from the start, with some kind of definition, then I don't think I, personally, would have had such a hard time with other preconceived notions.

That's also maybe just me being a poor developer in one way. I should have focused entirely on what functions the pieces performed and used them based on that, instead of what they were called. But I was interested in using things in an idiomatic manner, and I ended up getting confused because of it.

Because of habits that developed over time using server side MVC frameworks, and yeah, I know, "Ember is not MVC", I've had certain expectations when first digging into Ember. It probably took me that sixth months of on/off development with it to finally grasp what everything really is, not just what it's called. A lot of, hell, probably most people grokked everything in a few days, so it does make me feel a little foolish.

The team and community could probably sit down and come up with a document expressing what each of the concepts involved with Ember are called, define each, and list why they've been named such, and in my opinion, it would be really good for the community.

This document is fantastic. It's awesome to know where Ember is headed. And I know that there are the API and the guides, but I think there should also be a document that outlines the philosophy of Ember and its parts. Perhaps even an official tutorial that goes over a complete Ember program, beyond a "Hello world!" or a TODO app that utilizes most new or old features/concepts of Ember. For someone that's not constantly digging through the IRC and discussion forums, it's hard to find what the accepted practices are that aren't 6 months old. At least a centralized style guide or "Ember idioms" guide would be nice.

I also know that's it's easy to say those things without being on the team, or even having a full, complete understand of the individual components of Ember, but I truly think they would be useful.

@mattjmorrison mattjmorrison referenced this pull request in ember-cli/ember-cli Dec 16, 2014
Merged

Remove warning from README #2759

@aceofspades

Well said @nlutterman. Naming is really important and really helps build on previous knowledge but can also be an impediment when misleading. Using existing terminology might make ember seem more approachable at first, but can cause confusion up the learning curve. I've too often said route when I meant router or vice-versa. I like that using controller to represent both view controllers and model controllers is going way.

Case in point, Component doesn't feel like the right name for something that's routed to (and coupled to the app architecture), but rather something more generic and reusable. I hope there'll be a good name for a subclass that can represent the role more clearly.

@ahacking
ahacking commented Jan 2, 2015

@tomdale Thanks for the description of where things are heading.

It all sounds interesting but I'm still not seeing the high level picture of how the framework will hang together or how a 2.0 application will be composed. I would like to see a high level overview/diagram of the main parts with their responsibilities, and clearly see how both data, client events and server events flow through this proposed 2.0 architecture.

There has been mention of services previously and now rout-able components and deprecation of controllers but I see no mention of services in this RFC. It would be immensely useful to have the big picture/straw-man so we can see if it will stand up to the use cases.

Currently my controllers need to fetch data for dynamic model/data lookups, perform model buffering, dirty tracking, undo/redo and also orchestrate complex model persistence. I can't see components fulfilling these functions but they need to be taken care of somewhere. In React/Flux these concerns fall clearly into action-creator/dispatcher/store, but where do these things live in an Ember 2.0 application?

I haven't seen the moving parts required to support a uni-directional Flux-like architecture:

  • Are there high level actions?
  • Is there a dispatcher?
  • Are there stores/state managers?
  • How are actions that update state coordinated?
  • How would stores/state be updated in response to an action whether originating from the client or a server?
  • What in Ember 2.0 will support a unidirectional data flow?
  • Is Ember 2.0 an asynchronous or synchronous architecture from some dispatcher like concern down?
  • Has any thought been given to immutable datatypes as used in Om and React/Morearty.js? The reason I ask is that entire component tree rendering can be avoided completely via a simple === state test, and undo/redo is practically free.

On the DOM side of things has consideration been given for a DOM builder api, ala React? Whilst I concede handlebars templates may be more designer friendlier (with some caveats), I personally dislike using handlebars templates with their limited expressibility and issues of scope, context and inability to reference nested components.

I realise that handlebars/htmlbars being declarative was an approach to being able to efficiently and selectively update the DOM on change but that's largely historical baggage with a DOM diff approach. Using real JS and a DOM builder API I have no limitations on how I compose my components as the expressiveness is the full power of JS. Scope and context is pure JS, there is never any mystery. I can even use something like JSX to have HTML-like markup right in my code and avoid using helpers or the overhead, inconvenience and the bear traps of computed properties, which an approach based on declarative handlebars templates forces you into. I believe its imperative to have an official DOM builder API and let developers choose for themselves what html composition approach they want to use.

Whilst every detail in this RFC sounds mostly positive its not clear that Ember 2.0 based on this RFC has communicated a clear high level architecture, despite the significant detail provided.

@ef4
Contributor
ef4 commented Jan 3, 2015

I realise that handlebars/htmlbars being declarative was an approach to being able to efficiently and selectively update the DOM on change but that's largely historical baggage with a DOM diff approach.

@ahacking, that's a misunderstanding of the reason for declarative templates. Upstream Handlebars literally doesn't even support selective DOM updates, so that can hardly be the reason it exists.

Declarative templating is an architectural decision. It enforces separation of concerns. It helps ensure that no business logic accidentally starts leaking into templates where it doesn't belong.

This is one of those freedom-vs-integrity issues where programmers will always vehemently disagree, so I'm not trying to convince anyone. I'm just pointing out that we consider declarative templates a deliberate feature, not a performance optimization.

@ahacking
ahacking commented Jan 3, 2015

@ef4 thanks for your clarification of handlebars proper and the ember philosophy.

Its clear that Ember would not be able to do selective update efficiently if it didn't make templates declarative and the dom update driven off property changes.

I've also seen it stated that Ember will be moving towards a DOM diff approach based on what React has proven. Perhaps that is not the case? If so I understand the need to stick with templates and the lack of expressivity that comes with that, all the special helpers to do iteration and poor mans conditional logic plus the need to also use CPs to shape and prepare the data and provide logic values to those conditional helpers.

Given that components are the way forward and are about UI rendering of state and UI event handling, the template as an answer to separation of concerns argument seems a bit stretched.

The separation of concerns I would like to see in this facet of Ember are Component, DOM specification, DOM update (the real rendering), where DOM specification is a builder api and can be used by regular JS code or various flavours of templating be it handlebars, emblem, JSX or something else.

Forcing templates, computed properties and helpers to patch up for the lack of expressiveness in templates for Ember 2.0 seems a little anachronistic given the intent of components. I accept they will be needed to help people migrate existing code but that doesn't justify handlebars templates as the only way forward or even the right abstraction.

If I'm at odds with the Ember direction then so be it, ideally I'd like to see a lot of stuff removed from Ember that drive wtf moments such as CP's and observers and the need to use run loop deferred updates to fix surprises and feedback loops that pop up all the time.

My key concern is data flow and events, which CPs and observers really hurt. Templates drive me down that road and I don't want to go down it any further. Unless Ember has a good end to end solution for data flow which is easy to reason about (which it currently doesn't IMO) I believe the ability to develop and maintain ambitious web apps will remain a challenge, as will the ability for developers to get up to speed with Ember compared with competing frameworks.

I see 2.0 as an opportunity to paint a superior architecture and I'd like to see that picture clearly defined end to end so that all these feature changes and additions being discussed can be clearly evaluated. State management, data flow and event handling is immensely important for a predictable and easy to use yet powerful framework.

@kingpin2k

Ditching controllers doesn't seem that big of a deal. Code can be easily shared with mixins or using a service layer for what was past controller state.

I'm far more concerned about the conglomerate that we're calling routeable components. The name alone sounds like a future collision of undestanding. Unless they end up merging into the same thing it introduces yet another point of confusion where we're forced to distinguish between components and routeable components (component/view, arraycontroller/objectcontroller/controller).

Additionally it sounds like we're moving away from good clean separation of concern and just saying place everything in the routeable component. Feel free to fetch your model from the route as usual, but then put everything else in the component. I'm probably making a bigger deal of this than is necessary, it just seems like we're squeezing things down to a point where we end flipping the bird at the single responsibility principle and creating ginormous components.

The other issue I know has been mentioned a few times in here, is communication between components is a pain in the ass. With the concept of actions and bubbling and keeping components contained it feels like we will fall into tech support mode of having to repeat over and over "well routeable components allow actions to bubble, but normal components don't." It's unlikely that when I build a routeable component I want to have to force someone to define the portions of the API I want exposed. I probably want every communication that's sent to route out of my component.

All in all, I'm all for making sweeping changes if they'll work out for the best in the long run. As long as the code can still be easily maintained (consistent convention) and developed on by a team (good separation of concerns, and convention) then I'm happy (I know no one really cares if I'm happy ;) ) I just want to scream and yell and make sure those changes are scrutinized heavily and really fleshed out.

Those are my thoughts, keep up the awesome work.

@intuitivepixel

👍 @kingpin2k - 99,99999% Agreement!

@trek
Member
trek commented Jan 5, 2015

@ahacking

I've also seen it stated that Ember will be moving towards a DOM diff approach based on what React has proven. Perhaps that is not the case? If so I understand the need to stick with templates and the lack of expressivity that comes with that, all the special helpers to do iteration and poor mans conditional logic plus the need to also use CPs to shape and prepare the data and provide logic values to those conditional helpers.

DOM diffing is an internal approach to tracking and applying data updates to DOM. It has nothing to do with using or not using templates.

Templates drive me down that road and I don't want to go down it any further.

It sounds like what you want is is JSX or its JavaScript version. Why not just use React?

@klclee
klclee commented Jan 5, 2015

👍 @trek

@ahacking
ahacking commented Jan 5, 2015

@trek I certainly have been experimenting with React because of problems I have encountered in the Ember paradigm. React allows immutable data and unidirectional data flow which are very important architectural approaches IMO.

I also have an investment in Ember and I'd like to not throw that away if it can evolve in the right direction quickly enough.

Its the synchronous unidirectional flow I want, the so called " the data down" and state changing actions from the top , the ability to use immutable data types. Its about proper control over the state and state flow that doesn't require CPs and observer chain reactions as the basis of state proprogation and preparing of data for declarative templates.

If Ember can support true data down flow under the control of the application and immutable types then great. But CPs and observers don't work that way under the covers even though there may be the illusion of data down from what you express in templates.

I think this is within Embers grasp, I'm not a React fan, but a fan of deterministic state management and data flow that doesn't take indeterminate and surprising paths outside the control of my application to propagate state as Ember currently does. CPs and observers guarantee random state propagation and templates mandate their use.

@klclee well that was value add.

@gtrak
gtrak commented Jan 5, 2015

@trek in principle ember doesn't force you to use handlebars. In practice, all the observer glue makes it hard to use anything else, without knowing the details of observers.

We're also experimenting with React in a pre-existing ember codebase, but I was admittedly more a fan of React's data-agnostic approach before I even started using ember ~6 months ago.

In my opinion the project is moving in the right direction, but there still isn't a story for decoupled (and possibly immutable) data, which is why I really want to use more React.

@ahacking
ahacking commented Jan 5, 2015

@trek. Embers use of CPs and observers allows it to know when state has been changed so it can rerender parts of the DOM that are dependent on those changes. If Ember takes a Dom diff approach then declarative templates, helpers and CPs are not a critical component of achieving efficient Dom update anymore. Hence my previous statement, declarative templates and CPs/observers could become completely optional.

@stefanpenner
Member

if it can evolve in the right direction quickly enough.

OSS is an ecosystem which enables scratching ones own itch, and collaborating with others to work together in scratching those itches. Ultimately many hands make light work, and it is often quite fun.

@ahacking the theme of your comments are, this seems good. But I want more, and lets go quicker. I also wish for more momentum, but for this we would benefit from high quality and targeted contributions.

Rather then long comments that repeat previous comments. Let me recommend, focused proposals and patches to identify and solve the pain points near and dear to your heart.

Not everything can change instantaneously, but we can evolve over time.

Ultimately many hands make light work. They key is everyone working toward some compatible and common goal.

@stefanpenner
Member

@ahacking if you have time to chat about this, ping me on IRC or on google hangouts. I would love to try and work with you so we can continue to evolve front-end web app development.

@heat
heat commented Jan 5, 2015

How nice it will be a hang out on air to talk about that +1 if it happens. Count me in as a viewer

-----Mensagem Original-----
De: "Stefan Penner" notifications@github.com
Enviada em: ‎05/‎01/‎2015 14:35
Para: "emberjs/rfcs" rfcs@noreply.github.com
Cc: "Onezino Gabriel" zinogabriel@gmail.com
Assunto: Re: [rfcs] The Road to Ember 2.0 RFC (#15)

@ahacking if you have time to chat about this, ping me on IRC or on google hangouts. I would love to try and work with you so we can continue to evolve front-end web app development.

Reply to this email directly or view it on GitHub.=

@ahacking
ahacking commented Jan 5, 2015

@stefanpenner thanks, much appreciated. I'd like to get into some detail with yourself and anyone else who's genuinely interested in a productive discussion. I'm on IRC currently, my time-zone is GMT+10, hopefully I can catch you.

@klclee
klclee commented Jan 6, 2015

sorry @ahacking i was just agreeing.. indeed i should be more thoughtful... I would also love to listening to this discussion if it happens. With my experience on react the data down approaches (using props to affect state of children elements). i have found that to be limiting somewhat. I ended up with a bunch of custom event listeners fired triggered from the child element to affect the parent owed props. Many of this became unmanageable for me, and could end up having sync issues? Maybe there is a better pattern for that in react but i am no expert in it. Using observers which I think is managed in the run loop makes me sleep a little better i guess... However I love to hear what the different approaches can be...

@ahacking
ahacking commented Jan 6, 2015

@klclee no worries glad to have your input and the experiences in the mix.

In Ember 2.0 I am certain sending actions to parent will be very similar to how you do it in React. If you don't pass the handler into the component as an attr the child won't be able to call a handler on an ancestor. This mirrors how Ember components currently work assuming you're not using parentView hacks.

The patterns I'm most interested in from React is a the flux like approach of calling functors as top level action creators from ui event or action handlers within components. Those actions are handled by top level services/apis or stores. Once a store handles an action it should be only synchronous propagation of state to top level components and from those down to leaf components. I also want to be able to support immutable data types and see two way bindings and observers minimised as much as possible because of the problems they create.

I think this is all doable and closely aligned with where things are headed. Just need some consensus and agreement within core of the best way forward.

@mgenev
mgenev commented Jan 6, 2015

What happens when we are forced to use components more and not able to use controllers is we have to nest them more. Currently if we want to send an action up 3-4 levels, we have to declare the same code every level like this example shows:

http://emberjs.jsbin.com/hasehija/5/edit?html,css,js,output

Same thing applies when you are passing data down levels. Which is the reason, I have stayed away from nesting components this whole time, passing data down and sending actions up has a really annoying syntax. Will this be alleviated in any way in 2.0 when controllers come out and components become routable?

@hipertracker

Passing handlers down to subcomponents lead to mess, very soon. But more, it's just wrong and does not work at all if the component is not contained in the chain of nested scopes. Also using router to communication between different components (controllers?) does not make too much sense either (what if the component does not need to touch the server?) That's why Facebook invented Flux. I am afraid that Rect + Flux will cannibalize Ember and similar, old school JS frameworks. If the future is web components, than React is already a clean winner. Small example how simple it can be https://github.com/hipertracker/react-es7

@aceofspades

@mgenev I agree, forcing a declaration makes sense for abstract components, but not so much at the app level. I extended Component to allow the subclass to, depending on a config setting, either pass up all actions that are not otherwise declared, or declare an array of actions to pass along.

@ahacking
ahacking commented Jan 7, 2015

@mgenev, @aceofspades there are a valid reasons for localised action handling as well as global actions that change application state. I agree that actions up all the way as per current ember, and having to pass lots of action handlers down contingently is painful and that might be intentional.

In localised action handling the component doesn't have enough context to know what should happen so it calls the handler given to it by its parent on attrs. This is typical for collection as parent and item as child scenarios and for general purpose UI components.

At some point up the chain you reach a component that needs to change application state., eg 'add a comment to a post'. This is where I want to see global semantic actions used to effect application state much like the React reflux addon. Those global actions are handled by services and stores to change app state "at the top", which then starts the state propagation from top level components in the app hierarchy down to leaves, after which the render phase begins. Those top level components are what I believe routable components will be as route/URL is after all an important part of application state.

If you end up with state change logic in a component then that is a red flag that you should be putting that logic in a service or store (flux concept) and using global semantic actions like 'addComment'. State change logic in components will require long handler chains down and action propagation up so that each conponent along thr way can implement its piece of logic and that is painful. I think that pain is good as its the wrong thing to do and mixes concerns. Components shouldn't be managing application state or contain logic on how app state should be mutated, that belongs in services/stores. Components say what should happen, not how.

I'm just proposing how I see that things could work, not necessarily how it will in actuallity since not all of the vision of core has been set down in stone yet. I don't believe it's out of step with where things are heading.

We need different topics for these discussions as per @stefanpenner previous suggestion. Can we break out 2.0 into some themes? Do they need to be separate RFCs?

@aceofspades

Is there a strong advantage to using the same Component class to handle not only abstract, reusable, library objects, but also app-level concerns, and now routable ones? Are these responsibilities distinct enough to warrant special naming and behavior?

To me, it seems clear to that declarations make sense when crossing domain boundaries, i.e. library to app. You're mapping one namespace into another, and choosing which data to publish and which events to subscribe to. Once in the app domain, you've got a controlled scope and event namespace, and the advantages of convention-over-configuration apply.

@mgenev
mgenev commented Jan 7, 2015

@aceofspades I agree fully about declarations making sense when crossing domain boundaries. It comes down to this, in ember 1.x we have _the choice_ - if we want something to be tied to the app (domain) we'd use controller/view which is accessible from anywhere in the app. If we wanted something to be isolated and therefore portable between domains, we'd use a component. This worked well and was dry and great (minus the annoyance of nesting components, I'd personally much rather use a global pub-sub/dispatcher like @ahacking says, than pass an action and data 4 times).

Now that we're getting forced into components instead of controllers and views, in my opinion they have to be able to assume either role. They have to allow both easy access by bubbling events to the top automatically and inheriting data to the bottom automatically and be accessible by dependency injection like controllers are, or _if the user chooses so they can become isolated_ and force the declaration which serves as a handshake between 2 domains.

This would solve the problem.

@ef4
Contributor
ef4 commented Jan 7, 2015

Parts of this discussion are veering in weird directions that don't seem to understand how Ember works today, nevermind what's proposed for 2.0. Firstly:

Also using router to communication between different components (controllers?) does not make too much sense either (what if the component does not need to touch the server?)

That doesn't really make sense. Whether you'd involve the Ember router has nothing to do with whether you need to touch the server. The router exists to manage global application state and tie it to the URL, bidirectionally. If a component is going to alter the global state, it almost certainly does want to involve the router, otherwise you have broken web semantics.

Secondly, @mgenev's JSBin is ignoring how templates work in Ember. All of those component action handlers are completely unnecessary, even in today's Ember, because the innermost part of this template:

    {{#level-1}}
        {{#level-2}}
          {{#level-3 }}
            <button {{action 'handleAction'}}>
              Click me (yielded).
              "Inside a yield, the target points at the original target""
            </button>
          {{/level-3}}
        {{/level-2}}
      {{/level-1}}

Is still invoked in the context of it's owner, which in this example is the top-level application controller. So the handleAction event goes straight to the application controller anyway, and all those component action handlers are superfluous. This is not slated to change.

I would guess what you're really trying to illustrate is what happens if all those components have their own separate templates, and are not actually nested like this in a single template. In that case it's true that you'd need to be explicit about event propagation, but given the isolation you're choosing to use by giving each component its own isolated template, being explicit it entirely appropriate.

Also the proposed 2.0 syntax significantly streamlines the syntax for explicit event propagation. You can do it all within templates without creating action handlers in JS files at all.

@mgenev
mgenev commented Jan 7, 2015

@ef4 "I would guess what you're really trying to illustrate is what happens if all those templates have their own separate templates, and are not actually nested like this in a single template. "

Yes that's the whole point. If you look a bit closer at the bin, you'll see that both behaviors are illustrated.

" In that case it's true that you'd need to be explicit about event propagation, but given the isolation you're choosing to use by giving each component its own isolated template, being explicit it entirely appropriate."

I'm not choosing to. Right now if I want to not have to rewrite everything I write in the next 6 months, I have to avoid controllers and views hence to be dry and make my hierarchy, I have to be nesting components instead and I end up in that situation... Do you have a better suggestion?

@ef4
Contributor
ef4 commented Jan 7, 2015

Do you have a better suggestion?

Yes. It's nuts to try to avoid controllers entirely at this early stage. The code to support that is literally not written yet. This RFC exists so that the whole community can be involved in that process from the beginning -- not because it's imminently about to be done.

The stated recommendation is to use Controller (but not ObjectController or ArrayController, which are already deprecated on canary).

Everybody, including the core team, is literally writing apps today that still using Controllers, because that's how Ember apps are written today. We are not going to trash all of our code and yours by making it suddenly all completely broken. The deprecations are planned in very gentle steps so that you're never spending more than a little bit of effort making almost entirely mechanical changes, and nobody gets left behind or slammed with a giant chunk of rewriting.

@mgenev
mgenev commented Jan 7, 2015

I see. Use controllers and rewrite when the new features hit which will alleviate these issues supposedly, which answers my question. Thanks for the explanation.

@MiguelMadero

@mgenev a common misconception when it comes to components is that they're all about re-use, when IMO, they're all about encapsulation, being re-use and portability a side benefit. Even nested components are often domain specific.

I rarely see the need to bubble actions by more than 1-3 levels deep, and we nest components, a lot. However, we often encapsulate the actions at some sub-level. Often these actions result in a change to a model, if other parts of the application depend on the same model, they're automatically updated without having to know about the action that triggered the change.

@trek
Member
trek commented Jan 8, 2015

@MiguelMadero this. Components are about both, but people forget the isolation part.

In training I tend to tell people to think of components as functions: they have their own state (which is like a functions var statements) and passed in data (a function's arguments). You can use a function to isolate behavior and reuse behavior. If you only used it to reuse behavior, we'd all write many-hundred-line functions all the time which would make testing (and understanding) difficult.

@knownasilya
Contributor

I like how Vue.js explains the terms that are used in the library: http://vuejs.org/guide/#Concepts_Overview

@hipertracker

@knownasilya "Each Vue instance is associated with a corresponding DOM element." That's must be damn slow. React is using Virtual DOM, much better concept.

@knownasilya
Contributor

@hipertracker good and well, but we're talking about documentation and the ambiguity and connotation that some words carry when describing core concepts, and Vue.js does that well, without many assumptions. I suggest we do something similar.

@pixelhandler pixelhandler referenced this pull request in emberjs/ember.js Jan 15, 2015
Closed

EmberJS 2.0: The Future Of Ember Views #10232

@JasonAllenCorns

@knownasilya and @mgenev

As it turns out, you can trick the new syntax by doing something like:

{{#each this in paged itemController='messages.message-list-item'}}

it is strange, to me, that just giving it "this" would satisfy the syntax and controller.

@changeweb

If Array & Object controllers are deprecated in Ember 2.0, then how can we manage dependencies between Components by getting computed alias in Components? Something like:

Ember.computed.alias('controllers.application');
@joostdevries

@changeweb From what I know there are two cases here:

  • Access to properties from an arbitrary other controller (using needs in 1.x)

    For these cases, I think services offer a very nice pattern. You isolate any type of state or functionality that does not fit in the route and goes beyond the component at hand in a service.

  • Parent/child relations

    This should be doable with components but mutations and functional calls will have do be done using actions.

@changeweb

@joostdevries It looks interesting. Could you please give a small demo in jsbin for a better & clear understanding of Services?

@changeweb

This injection is working for controllers. If I remove App.inject('route', 'session', 'service:session');, this still works. But if I remove App.inject('controller', 'session', 'service:session');, this doesn't.

@joostdevries

@changeweb that's correct. Instead of "needing" the dependency you now have to inject it.

@samdelagarza

My two cents, depending on observables and computed properties across SRP boundaries (I.e. controllers) can lead to a mess. I've experienced this first hand and have preferred clear API boundaries across objects/services/interests.

Sam

On Jan 20, 2015, at 5:19 AM, Joost de Vries notifications@github.com wrote:

@changeweb http://emberjs.jsbin.com/quranekafa/1/


Reply to this email directly or view it on GitHub.

@changeweb

One may need to use lots of dependencies between components. needs in controller manages dependencies between controllers pretty well. We need something like needs or better dependency handler for route as well as components in Ember 2.0.

@changeweb

@knownasilya Sorry I've not seen them before. I used needs which is functionally equivalent to Ember.inject.controller().

Thanks for mentioning Ember.inject.service(). I think Ember.inject.service() will do the work by making properties easily accessible in the model hook.

@mgenev
mgenev commented Jan 20, 2015

@changeweb this stuff is just coming out now in 1.10 that's why you haven't seen it

@kristianmandrup

@hipertracker I totally agree with sentiments. Time has run out for "complete" MVC frameworks. Ember should be split up into smaller parts. Why be forced into a specific template language such as Handlebars. I just don't get it. It made sense at the time I guess (~4 years ago). All about being lightweight and flexible and build the architecture to your specific needs... Travel light ;)

@drogus
drogus commented Feb 1, 2015

Why be forced into a specific template language such as Handlebars.

You're not forced to use Handlebars.

@kristianmandrup

@drogus oh cool, well I assumed only Handlebars since I have yet to see an example of another Template language being used with Ember. How easy is it to opt out and use your own favourite (Reactive) rendering engine? Opens up some new exciting possibilities :)
I know there is a React-Ember library, but assumed it hooked into Handlebars as well... Thanks!

@changeweb

@kristianmandrup Have you read this can-reactjs-be-used-as-a-view-within-emberjs. For short Using React and Using Ember view.

I think you can do almost all react thing with Ember view.

@kristianmandrup

@changeweb Awesome! Must admit I had been a bit disillusioned about both Ember and Angular lately... will be interesting to see how Ember 2.0 will shape up in the end. It is key that it is suficiently lightweight/flexible and doesn't "lock you in" IMO

@taras
taras commented Feb 1, 2015

@kristianmandrup

Why be forced into a specific template language such as Handlebars.

You can use Emblem.js with Ember instead of Handlebars, but I'm not sure what it's future is. Ember is all about creating happy paths. Handlebars is the happy path for tempting with Ember. Once HTMLBars if fully baked into Ember, it will probably be possible to have other syntaxes use it to provide other templating syntaxes.

Ember should be split up into smaller parts.

Ember is already made out of many small parts. Templating is provided by Handlebars.js, Promise implementation is done with RSVP.js. The run loop is backburner.js. The router is router.js. There are many more.

All about being lightweight and flexible and build the architecture to your specific needs... Travel light ;)

Ember never aimed to be lightweight. That's why it's a framework and not a library. It's always been created to provide everything that developers need to be productive.

@kylecoberly

I agree with Taras- there are plenty of roll-your-own options out there,
and Ember is already pretty pretty modular.

On Sun, Feb 1, 2015 at 10:19 AM, Taras Mankovski notifications@github.com
wrote:

@kristianmandrup https://github.com/kristianmandrup

Why be forced into a specific template language such as Handlebars.

You can use Emblem.js http://emblemjs.com with Ember instead of
Handlebars, but I'm not sure what it's future is. Ember is all about
creating happy paths. Once HTMLBars if fully baked into Ember, it will
probably be possible to have other syntaxes use it to provide other
templating syntaxes.

Ember should be split up into smaller parts.

Ember is already made out of many small parts. Templating is provided by
Handlebars.js http://handlebarsjs.com, Promise implementation is done
with RSVP.js https://github.com/tildeio/rsvp.js/. The run loop is
backburner.js https://github.com/ebryn/backburner.js/. The router is
router.js https://github.com/tildeio/router.js/.

All about being lightweight and flexible and build the architecture to
your specific needs... Travel light ;)

Ember never aimed to be lightweight. That's why it's a framework and not a
library. It's always been created to provide everything that developers
need to be productive.


Reply to this email directly or view it on GitHub
#15 (comment).

@knownasilya
Contributor

The only thing missing is tree-shaking, to remove the unused parts and make your app speedier.

@mgenev
mgenev commented Feb 2, 2015

@knownasilya +111111

@heat
heat commented Feb 9, 2015

Ember never aimed to be lightweight. That's why it's a framework and not a library. It's always been created to provide everything that developers need to be productive.
I agree
It's what I looking for. It sounds great when I hear about decoupled parts and pluggable. But nowadays what I want is productivity.

@davidlormor

So I just wanted to chime in again on the discussion around routable components - I think I've seen the light, so to speak. After migrating my "very large" ember project to ember-cli and adopting a "component-centric" development approach, I "get it"...actually it feels painful when I have to spin up a View to wrap my route-associated templates now.

While I still feel there is definite validity to the arguments around the separation of concerns, object/array controller associations, and service controller, I've heard a lot from core team members lately via various channels and am confident that they're driving this forward in a way that will properly deal with those concerns. The development momentum I've built the past couple months using this approach can't be denied, and am super excited about the future of this framework!

@QuantumInformation

best news of all:

Instead, we plan to do the vast majority of new work on master (behind feature flags), and land new features in 1.x as they become stable.

@adrianboston

NSArrayController->selectedObject cici n'est pas une cocoa

@wycats wycats locked and limited conversation to collaborators Feb 21, 2015
@wycats
Member
wycats commented Feb 21, 2015

This was a really awesome discussion that significantly informed the Ember 2.0 direction. From this point forward, it makes more sense to open new RFCs for new features. If there's a feature you want implemented, definitely start a conversation about it.

Pieces of this RFC have since been expanded to full RFCs, or have been implemented, so definitely continue any relevant discussion on those RFCs.

For the big enchilada, expect an RFC for Routable Components to come in the next few days. You can also follow along with the new component implementation at emberjs/ember.js#10501

@mmun mmun merged commit ae0215d into master Jun 7, 2015
@mmun mmun deleted the ember-2.0-rfc branch Jun 7, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.