Should my logic be outside of my Polymer elements?

873 views
Skip to first unread message

David Notik

unread,
Aug 26, 2014, 8:01:43 PM8/26/14
to w...@dartlang.org
Struggling w/ some high level conceptual stuff here.

(I've got a pure Polymer app: https://github.com/DaveNotik/dart-stack/tree/dev.)

So far, I've put my logic (e.g. a getItems() method that queries the database) in my elements themselves (e.g. inbox-list) and I trigger it on attached(). I have <template> conditionals around my elements that show them based on my app.selectedPage, so attached() is always fired when I want to show that element. That's worked fine so far.

But I've got the idea in my head that the OOP way is to put that logic outside the element, in some controller, and maybe triggered by my route. The argument is that the element should just represent the object and maybe include some "decorators" but the real meat should be elsewhere.

The problems I have with that include:
  • Relying on routes or something other than attached() kills the ability for the app to work as a set of static HTML files. Right now, even without my Dart server, I can pretty much use my app because I'm just clicking things which attach certain elements, thereby triggering whatever methods I call in attached(). An added benefit here is that I can more easily wrap my app w/ PhoneGap. The moment I'm relying on server or client side routes, I'm killing that ability.

  • Doesn't that fly in the face of encapsulated elements that are reusable? I mean, I guess I could pass in stuff from the controller via published properties like list="{{mycontroller.myInboxList}}" but I'd have to do a lot to handle what might be passed in, and this just feels like I'm treating it as a public element and doing unnecessary work.
I want to be able to have my Polymer app work over the internet (I've got a Dart server that serves it, handles server side routes, etc.) but also work as client side code so I can e.g. wrap it w/ PhoneGap.

I feel like I'm at a pivotal point, and need some high level guidance/best practices.

Thank you!

--D


Paul Brauner

unread,
Aug 27, 2014, 4:36:43 AM8/27/14
to w...@dartlang.org, seth...@google.com
Hello David, I've also struggled with this kind of issues until I read an eye-opening comment from +Seth Ladd remarking that polymer (web-ui at the time) applications can be architectured as Model View ViewModel (http://en.wikipedia.org/wiki/Model_View_ViewModel) applications. In other words, you may want to architecture your polymer application in a way that classes implementing you polymer elements are viewmodels: they maintain the state of the UI element (like "selected") but not the state of the application (like "article read").

Paul

--
You received this message because you are subscribed to the Google Groups "Dart Web Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web+uns...@dartlang.org.
Visit this group at http://groups.google.com/a/dartlang.org/group/web/.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/web/CACekCDnFBnaS3bRkjh6aX3n-Y6GJJ08xDpzLXuCLay1gaBGGgQ%40mail.gmail.com.

Jacob Macdonald

unread,
Aug 27, 2014, 10:54:29 AM8/27/14
to w...@dartlang.org, da...@woven.org
This is definitely a topic still open for debate, as Polymer itself doesn't really provide any specific guidance or best practices in this area, and leaves it up to each developer to decide what is best in their particular situation.

I personally would argue that the simplest solution that works for all the situations you care about is the best solution. In this case that very well might be what you are currently doing, just putting the logic inside the elements themselves. While it may feel wrong, there is no need to over-generalize elements unless you plan on sharing them externally or using them across multiple applications.

If at some point later you do need to make your elements more general, it shouldn't be hard to refactor this so they take in a ViewModel object via public properties. This model can also have a lazy interface so you can still use attached() to fire off actual requests. 

David Notik

unread,
Aug 27, 2014, 12:38:20 PM8/27/14
to Jacob Macdonald, w...@dartlang.org
Thank you, Jacob!

What is the most sophisticated public example of a pure Polymer application? Ideally, one that demonstrates some kind of framework approach.

In my own app (https://github.com/DaveNotik/dart-stack/tree/dev), I've got a good deal going (client, server, communicating between them, routes, sign in) but I'd love to see something else non-Angular.

Matthew Butler

unread,
Aug 27, 2014, 1:07:21 PM8/27/14
to w...@dartlang.org, jak...@google.com, da...@woven.org
While unfortunately I have nothing public I can share. I've worked on a couple of projects now with just Polymer dart.

I've taken several different approaches with Polymer components. 

1) I've created a 'base class' which itself extended PolymerElement. However it did not have any associated .html file. It was only designed as a super-class which handled adding in some of the functionality I wanted like handling ajax stuff which was common to most of my components. I then created subclasses which extended my superclass (and there-by PolymerElements). These had the associated CustomTag annotations as well as associated .html files. They were also the 'model' for the object they represented. Unfortunately this made them really heavy models and very tightly integrated with model, view and controller all bundled together. Thus when I had to make a change or add a new feature they did not 'grow' well.
I also tried similar using mixin's to include common functionality. But again I didn't like specifying that each component had to expect certain functionality and tying it in as I did made updating difficult.

2) I've created a model class for the respective data types which may be used, and kept all similar but slightly different code individualized to each component. It made it slightly easier to add new functionality without breaking things, but unfortunately it also really broke the DRY pattern and just made the classes seem a little bloated.

3) More recently I've continued with using a model, and then using a singleton type class for handling ajax stuff. It could probably be a static class if I really wanted but with the singleton I can keep track of data which I may want to persist between elements a little easier (a type of caching really). This is singleton class is initiated by classes which may need it in the created constructor. It handles stuff like ajax calls which expect a model that implements toJson. Nice thing is that when I need to do some local testing I can just swap out the ajax class with a dummy one and I don't need to update each and every model in the app. Now each component is detached from the backend server API, and if I make any changes there I don't need to update each and every component which uses it.

The singleton class just uses a factory constructor which either initialized it on first use, or returns a cached copy otherwise. The only real gotcha I ran into is that if I didn't always have one copy of it alive, then it would be GC'd and constantly creating a new copy when needed losing out on any caching advantage. However since I use the polymer pattern of having the entire app as a component with multiple sub-components, just initializing it in the main app helped to solve that issue.

Matt

michael.haubenwallner

unread,
Aug 28, 2014, 3:19:16 AM8/28/14
to w...@dartlang.org, jak...@google.com, da...@woven.org
Talking of polymer.dart i think of https://github.com/dart-lang/dartdoc-viewer 

David Notik

unread,
Aug 28, 2014, 10:27:23 AM8/28/14
to Matthew Butler, w...@dartlang.org, jak...@google.com
Thanks Matthew! I'm processing this and will try some new ideas as I deliberately but slowly refactor as I move forward. A "best practices" guide and sample "full Polymer Dart application" (with routes, server side, the whole deal) would be very helpful I think.

--D

Robert

unread,
Aug 28, 2014, 11:57:02 AM8/28/14
to w...@dartlang.org, butler....@gmail.com, jak...@google.com, da...@woven.org
An interesting topic indeed, I'm also working on this at the moment and hope to publish something soon! 

Federico De Faveri

unread,
Sep 17, 2014, 4:38:43 AM9/17/14
to w...@dartlang.org, butler....@gmail.com, jak...@google.com, da...@woven.org
Any news on this topic? I'm really interested about it.

David Notik

unread,
Sep 17, 2014, 12:14:19 PM9/17/14
to Federico De Faveri, w...@dartlang.org, Matthew Butler, Jacob Macdonald
Actually, I ended up incorporating ViewModels.

Check out my approach! I'd love feedback. What say you, Jake, Matt, Michael, Robert?

http://mycommunity.org (Live, sign up!)

--D

Jonas Kello

unread,
Dec 1, 2014, 4:36:54 AM12/1/14
to w...@dartlang.org, defa...@gmail.com, butler....@gmail.com, jak...@google.com, da...@woven.org
Very interesting topic! 

I've been doing MVVM in C#/XAML since the pattern was first discovered (6-7 years ago?) and labelled MVVM (by the Microsoft Blend developers if I recall correct, although Fowler already had it described as "Presentation Model"). What is important to understand about this pattern is that it entails making dedicated models that only support the view (through data-binding) and nothing else. Here are some points I have found:

* You want your DTO objects (that support transfer) separate from your View Models (that support data-binding). Also you do not want to wrap DTO objects inside View Models because that creates unwanted coupling. Instead you want to map them (which was the purpose of the AutoMapper project if I recall correct).

* You want your DTO objects immutable, so if you put them inside a cache, they will not change. You want your View Models mutable, so the user can change them on-screen through data-binding. This is another reason to not use the same model for ViewModel and DTO.

* You want every data-biding to be a 1:1 to a property on the ViewModel. No expressions, adapters, converters etc. in the binding. Data-binding can be very hard to troubleshoot otherwise (XAML has the notion of binding converters, I've used it and it ends up as a total mess). The binding should be very clean, just stating the name of a property on the ViewModel. Having separate properties for every binding is made possible by having dedicated View Models that has no other concern than to support the data-binding. If we force the use of the same model for both data-transfer and binding the risk is high that we use complex binding expressions which in turn will make us hate data-biding as a concept :-). Consider eg. you have a DTO object with FirstName and LastName but on-screen you want to show FullName. It is very easy to be drawn to making a single class with FirstName and LastName, using it to transfer, and then creating a binding expression that combines both properties to FullName. The better way to do this is to create a separate DTO class with FirstName and LastName, and a separate ViewModel class with Fullname. Then create mapping code that reads the DTO and fills the Fullname of the ViewModel. Then a simple binding expression that binds to the ViewModel's Fullname property. It might seem unnecessary in this simple example, it is more obvious once you create more complex scenarios.

* There are two main approaches to MVVM: view-first and model-first. If you use view-first then the View is created first and then finds its related ViewModel. If you use model-first then the ViewModel is created first and then finds its related view. I am still processing how this relates to Polymer...

* There are two types of models. Those that have their own view and those which is part of another view. Eg. you might have a model that is just a list item model but the template of the list item is defined in the view (HTML) of another model. I usually refer to the models that have a view as ViewModel and the other type as ViewItem.

Regarding a polymer app to look at, I am currently investigating the Chrome Dev Editor (https://github.com/dart-lang/chromedeveditor). It has a framework type setup that looks interesting.

I am still processing how my past MVVM experience maps to Polymer (if it maps at all). So please add any comments, critique or questions and let's keep the discussion going :-):

Specifically, I am currently contemplating the question in the original post. Is the element the ViewModel or should we treat the element as "code-behind" and add a separate VieModel class for each element.

/Jonas

mark.hatsell

unread,
Dec 1, 2014, 6:07:10 AM12/1/14
to w...@dartlang.org, da...@woven.org
I'm also pretty interested in this topic as there is not really any info available regarding the best way to do all this. At the moment I am breaking one of your rules in that I am effectively wrapping my DTO objects inside the ViewModels. I probably should be mapping instead but this seems a lot of work in the absence of any sort of automapper class.

Keep us posted on how you get on. I also started looking at the Chrome Dev Editor but it's quite a big project to get my head around.

Mark

Michael Gerlek

unread,
Dec 1, 2014, 8:12:19 AM12/1/14
to w...@dartlang.org, da...@woven.org
Interesting discussion indeed, and +1 to the idea of producing a non-trivial (but not overly complex) demo app which shows off dart+polymer to best advantage. (Happy to help out if needed.)

For what's its worth, I did some C#/XAML coding back some years ago, and partly inspired by the work I did then the approach I'm taking in my dart app today is roughly this:

- Each polymer element represents a piece of UI. It tracks only the state of that UI component and no more. Data binding is used between the data in the element class and the display of the data in the html.

- The various polymer elements (mostly) do not communicate between themselves.

- The polymer elements do communicate with a central singleton class, cleverly named "Hub", which is responsible for overall command and control. The hub exposes methods like "doSomeAction()" and "doSomeOtherAction()" which are invoked by the UI components. For example, a "file manager" UI component would invoke hub.doOpenFile() when the file manager's OK button is pressed.

- There are a bunch of classes which are responsible for implementing behavior and actions. These are not UI elements, just pure dart. The hub uses these classes to implement the doXXX() functions. These classes (generally) do not communicate between themselves. Continuing the example, the doOpenFile() method would call into the FileSystem class which would read the file from disk or whatever.

So far, this model seems to be holding up. It has the nice benefit that, because I'm implementing all the key functionality with doXXX() methods in the hub, I now have the ability to "execute" the app in a "headless" fashion: that is, I can write a set of calls to those hub methods so that I can unit test (or demo) the app without actually touching any of the UI components.

-mpg

Michael Haubenwallner

unread,
Dec 1, 2014, 8:41:51 AM12/1/14
to w...@dartlang.org

--
You received this message because you are subscribed to a topic in the Google Groups "Dart Web Development" group.
To unsubscribe from this topic, visit https://groups.google.com/a/dartlang.org/d/topic/web/DhODVoTFVbk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to web+uns...@dartlang.org.

mark.hatsell

unread,
Dec 1, 2014, 8:45:56 AM12/1/14
to w...@dartlang.org, da...@woven.org
Thanks Michael. 

So how does data from your "real" model get to and from the Element class when data-binding updates occur? If for example the user changes a value via the UI, this will data-bind to the Element, but then how does the data in the actual model get updated? At the moment I have references to the real model in my Elements but I'm not sure this is really desirable.

Mark

On Wednesday, August 27, 2014 1:01:43 AM UTC+1, David Notik wrote:

Michael Gerlek

unread,
Dec 1, 2014, 8:50:26 AM12/1/14
to w...@dartlang.org, da...@woven.org
Right, yeah… It’s done via a function call into the hub:


FilePickerElement {
  @observable String file;
  …
  onSelection() => _hub.doOpenFile(file);
}


So the model is actually living in the hub, but also lives as a “copy” in the UI element. I recognize this is almost certainly wrong, and I’d like the UI element to reference the hub’s data as an observable directly, but I’m not there yet.

-mpg


--
You received this message because you are subscribed to a topic in the Google Groups "Dart Web Development" group.
To unsubscribe from this topic, visit https://groups.google.com/a/dartlang.org/d/topic/web/DhODVoTFVbk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to web+uns...@dartlang.org.
Visit this group at http://groups.google.com/a/dartlang.org/group/web/.

mark.hatsell

unread,
Dec 1, 2014, 9:23:04 AM12/1/14
to w...@dartlang.org, da...@woven.org
OK - I see what you are doing now. So every UI change effectively invokes a function in "hub". Presumably the hub must also call into the Element classes (to set the initial values etc.). I actually do reference data in the model directly but somehow that doesn't feel quite right either. I have a lot of code in my Element classes that looks like:

@ComputedProperty("model.selector.selectmode")
@observable
bool get selectorenabled => (model != null ? model.selector.selectmode == Selector.SelectNormal : false);

void set selectorenabled(bool val) {

  if (val) {
    model.selector.selectmode = Selector.SelectNormal;
  } else {
    model.selector.selectmode = Selector.NoSelect;  
  }
}


Basically I'm converting some data in my real model (model.selector.selectmode) into a form that can be data-bound in my Elements (selectorenabled).

Mark

On Wednesday, August 27, 2014 1:01:43 AM UTC+1, David Notik wrote:

Anders Holmgren

unread,
Dec 1, 2014, 3:02:01 PM12/1/14
to w...@dartlang.org
Interesting. Reading Jonas' post I realised that I've kinda naturally evolved towards the mvvm pattern.

I tend to name things (in my head) slightly differently. I think of the M models as domain models. They capture the business concepts independent of any view. And the VM models as application models. They model your app. Same diff though but may help to focus thinking.

In a polymer context I would add the following
- don't make your polymer elements your view models. Make them very small and simply contain a reference to your view model.
- make sure everything other than the polymer elements depend only on the observe package, not polymer
This means your entire application behaviour is unit testable outside the browser.
That's another motivation for very simple binding expressions. Keep the view as simple and stupid as possible so the behaviour is in the view models not the view.

I'm currently in a major refactor making my model views heavily frp based

Jonas Kello

unread,
Dec 4, 2014, 4:52:19 AM12/4/14
to w...@dartlang.org, da...@woven.org
Actually I think mapping the DTO rather than wrapping is is more of a "guideline". Keeping the DTO immutable and never binding directly to the DTO however I would say are more like "rules".

At one point I was using AutoMapper (in C#) but I did not like it much. Although it's called "auto" it did required setup for may cases and also the ability to debug became more limited. So now I usually have one "Map" class per application module with static methods like "MapXXXDtoToXXX" and manually write the mapping code. I also sometimes wrap the DTO inside the ViewModel, basically because I am lazy :-). In general I have not found any problems with wrapping other than creating the coupling feels wrong. I guess unit testing the ViewModels can get more complicated if you do a lot of wrapping since then you need the DTOs in the tests as well.

/Jonas

Jonas Kello

unread,
Dec 4, 2014, 5:21:29 AM12/4/14
to w...@dartlang.org, da...@woven.org
The "hub" part is interesting. I usually have something I call a "service" that I dependency inject into the ViewModels. This service will have logic for doing things, like saving a file etc. However these services are stateless themselves.

The "hub" sounds a little like the mediator pattern:


There were some people using that in the MVVM C# community:


I have not really tried it fully myself though so I cannot say if it is a good idea.

Would you say that your "hub" follows the mediator pattern?

/Jonas

Jonas Kello

unread,
Dec 4, 2014, 5:30:49 AM12/4/14
to w...@dartlang.org
Thanks Anders! The use of a separate class acting as ViewModel instead of having the Polymer Element class itself act as ViewModel is something I'm contemplating to do myself and seeing that others doing it really helps me decide! 

One question about the separate ViewModel class. Do you annotate the variables with @Observable etc. Or do you manually declare the ViewModel class with the Observable mixin and call notifyChange etc.?

Btw, in one of our C# projects we are currently re-factoring towards making the ViewModels more reactive rather than having them actively query for data themselves. That is also an interesting topic! :-)

/Jonas

Michael Gerlek

unread,
Dec 4, 2014, 7:59:26 AM12/4/14
to w...@dartlang.org, da...@woven.org
Yes, exactly — my hub class is a Mediator.


<aside>
I have been thinking about my architecture as a result of this thread, and whether using signals/events is a more natural way of doing things. I could certainly see my various components running signal flags up the mast (“User requests new file to be loaded!” “Aye, Captain, loading new file now!”…), and that would go a long way towards making things more async, esp. as I begin to embrace the use of Futures everywhere. [eagerly anticipating async/await to be ready for use!]

However, I’m a bit too old fashioned and so it will take me a while to embrace this model. In particular, with my various components sending and receiving signals asynchronously and almost autonomously, I worry about the maintenance side of things. Specifically, at the architectural level:

(1) there is no way to see what components raise what events
(2) there is no way to see what components catch what events
(3) there is no way to see what kinds of events there are

I suppose (3) is easily addressed by having a nice Event class hierarchy. But (1) and (2) remain a concern. Looking at the class properties and members, or the generated docs, or a generated UML diagram, that information is not presented. Someone coming from the outside to look at my code will have no way of understanding what the high-level communication and interactions patterns are.

Hmm, maybe this is a job for @annotations...
</aside>

-mpg

Anders Holmgren

unread,
Dec 5, 2014, 7:21:28 PM12/5/14
to w...@dartlang.org
Damn I just wrote a long reply to this and accidentally hit the discard button instead of post. Can't believe there was no dialog to ask if I really wanted to throw away the draft!?

Will respond later

amacd...@thecape.ca

unread,
Dec 12, 2014, 6:54:54 AM12/12/14
to w...@dartlang.org
Anders,

I am also looking at frp lately. I am interested to know how it goes. There was a pub library called frappe that you may also have seen to support that approach.

Glad to see discussions like this one. They really help!

gex.d...@gmail.com

unread,
Dec 12, 2014, 10:07:16 AM12/12/14
to w...@dartlang.org, amacd...@thecape.ca
Sorry, i do not follow here : What "frp" stands for ?
Thanks

Gerald Reinhart

unread,
Dec 12, 2014, 10:10:09 AM12/12/14
to w...@dartlang.org, amacd...@thecape.ca
Got it :  functional reactive programming (FRP) 

Anders Holmgren

unread,
Dec 15, 2014, 2:24:48 AM12/15/14
to w...@dartlang.org, amacd...@thecape.ca
Well it's going slowly. On the one hand I'm excited that this will lead to a really powerful and flexible design. On the other hand I'm finding it diabolically hard to get this code to a reliably unit tested state.

Complicating my life is that I'm using a combination of frappe and the observe package. As it's a polymer app it needs to use observe on the UI facing parts, but also there is nothing similar to ObservableList etc that I can see in frappe. Probably by design as it works with immutable objects, but I need to manipulate a reasonable sized list rendered in core-list so can't afford to change the whole list each time an element changes.

Anyway at a more high level, let me explain what I'm doing.

I'm introducing a new layer to my UI. I have the usual view and view model stuff plus DTO's. What I'm adding now is effectively a client side instance of a REST resource. Unlike the DTO's these are not anemic domain objects. They handle all the comms with the rest services and expose frappe properties / observe collections of their data. As the data updates (either from an action initiating in the UI or potentially web socket event etc) the properties will update and be picked up by listeners.

I also have higher level domain objects that aggregate data from other domain objects. i.e. they don't correspond 1-1 with a particular REST resource but are derived from them.
The properties they expose are derived from properties of the underlying domain objects. This gets challenging as I'll get to below.

Finally I have view models that are similar to the higher level domain objects in that their data is derived from other models.

I have written a whole bunch of helper functions that I'll make available at some stage for things like
- deriving observable lists from other observable lists. i.e. this is effectively like Stream.map except for observable lists.
- aggregating observable lists together (this is effectively an observable list of observable lists of items that aggregate into an observable list of items). So the items in each list can change and the number of lists being aggregated can change.
- functions for converting between frappe classes and observe classes. For example converting an observable list into a Property<List>

And this is where I spent hours on the weekend pulling my hair out trying to get to unit tested code for. Specifically the problem I was trying to solve was

- I have a status property (Property<Status>) in a higher level domain object that is derived from the status properties of a list of other domain objects.

class DomainObjA {
   Property<Status> status;
}

class HigherLevelDomainObj {
  ObservableList<DomainObjA> aObjs;

  Property<Status> get status; // derived from aObjs->status

}

There's actually a DomainObjB that also has a status that affects the higher level status but I'll leave that out here.

So the question is how to implement HigherLevelDomainObj.status

Remember that aObjs is an observable list so the contents can change over time and the DomainObjA.status is a Property so also changes

Step 1/ I wrote a function that takes an ObservableList and turns it into Property<List>
Step 2/ A function that turns an ordinary List<Property<Foo>> into a Property<List<Foo>>
Step 3/ combine these two functions as follows

ObservableList<Property<Status>>   => Property<Property<List<Status>>>
then flatMapLatest on Property<Property<List<Status>>> to give Property<List<Status>>
then I can fold on Property<List<Status>> to create a Property<Status>

The function looks like

Property<List> observableListOfPropertiesToPropertyList(ObservableList<Property> ol) {


  Property<List<Property>> plp = observableListToPropertyList(ol);

  Property<Property<List>> ppl =
      plp.map(listOfPropertiesToPropertyList).asProperty();

  Property<List> result = ppl.flatMapLatest((pl) =>
      pl.asStream()).asProperty();

  return result;
}



My brain exploded at some point trying to debug the unit tests. It seemed to kinda work when the input properties had initial values but not otherwise but they failed in strange ways.

So in summary, I still have a vague hope that this well end up super awesome but definitely not for the feint hearted

A

Jonas Kello

unread,
Dec 15, 2014, 6:37:53 AM12/15/14
to w...@dartlang.org, amacd...@thecape.ca
Hello Anders!

Thanks for the update! Still processing your higher level domain objects concept :-) But I have one quick comment on the "client side instance of a REST" layer. For me it sounds that this layer has responsibilities similar to the "store" concept in the Flux architecture described below, would you say that is true?


I have this kind of concept in my C# MVVM code but it is not explicit, I sometimes call it a "manager" etc. Basically it is a client-side holder of state that is shared between multiple ViewModels and it can emit events about changes to that state, and communicate with the back-end to fetch or update this state. I am thinking about introducing a more explicit "store" concept into my architecture but I am not there yet. Also I have just read briefly about Flux so not sure my understanding of the "store" is correct. So any comments on this is welcome!

/Jonas

Anders Holmgren

unread,
Dec 15, 2014, 2:49:43 PM12/15/14
to w...@dartlang.org
Hi Jonas

From a quick reading there does seem to be similarities. I am also updating the client side REST resources via actions (command pattern with undo support).
In addition to undo it also allows support for retries, aggregating requests to the server, serialising updates to a resource etc.
Also this would be the point where I'd likely add offline support in the future

The base class has a method like

Future apply(Action action);

Additionally there is a property

EventStream<CompletedAction> get completedActions;

So as actions complete they feed into the stream of completedActions. These will (via view models) end up feeding into things like paper toast's etc.
Also they contain info on start and end times for the action plus success / failure, number of retries etc which I'll like feed into analytics at some point

A

Gérald Reinhart

unread,
Dec 19, 2014, 9:20:57 AM12/19/14
to w...@dartlang.org
Hi all,

  Very interesting topic !
  
  I havn't processed in my mind all of this mail thread BUT here is my feeling:

 one (among several) aim of the presented designs is to make our polymer project testable without launching any browser : if we can do that, it would be perfect 

 BUT

 I fear that the desgin become too complicated because of the aim

If I had to choose between 
 (1)
   - simple code
   - unit tested through a browser
 (2)
   - complicated code
   - unit test without launching any browser

I would choose the first one.

So now considering that the senario (1) is possible, I will go this way.

   - Continuous Integration running on Drone.io



A

--
You received this message because you are subscribed to the Google Groups "Dart Web Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web+uns...@dartlang.org.

Jonas Kello

unread,
Dec 19, 2014, 2:04:32 PM12/19/14
to w...@dartlang.org, gerald....@gmail.com
Actually to make it more testable is not so complicated. 

Like Anders said previously in this thread, you just keep the class that inherits from PolymerElement empty except for a reference to another class that only inherits from observable (we call this extra class a ViewModel). Eg. your class that inherits from PolymerElement has a single property "viewModel" that references this extra ViewModel class. All the bindings in your template will be "viewModel.XXX" instead of just "XXX". Now you can easily test all the logic of the ViewModel class because it only depends on the observable package.

/Jonas

Gérald Reinhart

unread,
Dec 19, 2014, 3:24:25 PM12/19/14
to w...@dartlang.org
Ok, Jonas. Thanks it makes easier to understand. Will try it.

Gerald

Reply all
Reply to author
Forward
0 new messages