In angular we are used to DI, services, routing and the like. I am wanting to hear from people who have projects that have transitioned to polymer from angular and what they found to be correct way to approach and accomplish similar feats in Polymer. I've found the easiest comparison to be made with the directives and custom polymer elements but from there things diverge.
How do we go about sharing some sort of "service" in a polymer app and create some sort of DI container where we can use to mock dependencies? Also would like to know how you accomplished (routing/nested routing) where before you could have used the ng-Router or UI-Router.
This might help you get going with routing https://github.com/erikringsmuth/polymer-router-demos.
When you use custom elements your APIs are HTML attributes. For now you have to test in the browser with Jasmine or QUnit since Node and PhantomJS don't support custom elements yet. You test by creating an instance of the element, calling a public function on it, and asserting the result.
HTML Imports are loosely equivalent to DI. I haven't seen any mocking libraries for HTML imports yet.
Services will be an interesting topic going forward. Right now you either include business logic in the custom element or have some external script calling public APIs on your custom elements and binding everything together.
Related
Currently looking at upgrade paths from Angular 1 -> Angular 2 and one things we've done with our Angular 1 work is reuse some of our components on public facing non-app pages.
These pages are effectively static HTML (though they are rendered by Rails) and then some Angular 2 components are dropped into the page in places. This worked from with Angular 1, we simply bootstrapped the document element with a module that provided the directives and components we needed. There is no routing at all.
With Angular 2 it looks like it is all or nothing. You declare a single root component and everything is rendered through that. This would be a big shift for us and I'd like to avoid changing how we are doing things on these public facing pages.
Is it possible at all to just use Angular 2 components as needed in static HTML pages or will we need to move to a single root element SPA design?
In a nutshell, what I'm asking is if it is possible to have a mix of static content with dynamic angular components sprinkled within, or must all angular components live within a single root element on the page?
So this is simpler than I originally thought. In the Angular 2 docs it has some specific wording around bootstrapping multiple apps.
Bootstrapping Multiple Applications
When working within a browser window, there are many singleton
resources: cookies, title, location, and others. Angular services that
represent these resources must likewise be shared across all Angular
applications that occupy the same browser window. For this reason,
Angular creates exactly one global platform object which stores all
shared services, and each angular application injector has the
platform injector as its parent.
Each application has its own private injector as well. When there are
multiple applications on a page, Angular treats each application
injector's services as private to that application.
So it seems clear that this is intended to be possible and that multiple apps share service resources which is what I would hope for.
I've done some trivial tests with multiple bootstrapped components and it works fine. One thing I have not yet tried is bootstrapping an Angular 2 attribute directive for use outside of Angular 2 components. I suspect that won't work and that bootstrap only works with Components and not Directives.
In terms of guidance, I would suggest that Angular 2 is not really designed for sprinkling behaviour throughout a static page and probably should not be used that way. Rather, while you may have multiple sections of your paged defined by multiple apps, that components should make up nearly all of the document/interface.
we simply bootstrapped the document element with a module that provided the directives and components we needed. There is no routing at all
That's exactly how I'm currently using Angular2. See the example at https://github.com/niczero/ng2-es5-file-upload/blob/master/demo/index.html -- some of my 'static' pages are generated by perl in the same way you are using ruby.
As an aside, being able to use your modules both ways is much easier if you embrace Universal Module Definitions
I didn't see any guide on the website. Can we use polymer with angular.js?
Others options?
We are currently investigating the use of Polymer alongside Angular and this article gives a demonstration on how it can be achieved:
Using Polymer WebComponents with Angular.js
The author does conclude by saying not to mix the two worlds, but he admits that is just an opinion.
Binding values from Angular to Polymer seems to work well. The issue is controlling the flow of information out of Polymer back into Angular.
This directive helps with this:
angular-bind-polymer
There are a couple of things I don't quite like with this:
You have to decorate your elements with the directive.
You have to enable reflectToAttribute in your Polymer element, which if it is a large javascript object for example could be ugly.
Having said all that it works, so if you think it will work for you then evaluate it.
You might want to start with the aptly named Polymer Starter Kit.
As for use with Angular, Polymer elements work well with Angular 2.0, currently in Alpha.
When I first looked at Play and went through all the samples, I was pretty excited by the zentasks sample and the fluid, clean, effortless Javascript routing that left the work of rendering things to Play. But we decided instead to go with Angular.
Upon going down that road, I thought that Angular would control all aspects of rendering.
However, we have a page that has to get a socket. We were having the socket made on the server, so for now, we still have a Play (Scala) template doing that. We have pared it down to pretty much nothing: create the socket and then inject it into the Angular context.
But we are also trying to do Protractor tests and that is made uglier by having to figure out how to accommodate the Scala template.
Question: should we just ditch the scala template and have the Angular controller call the server and get the socket? That was my favored approach to begin with.
I'm currently working on two Play apps with Angular and in both we decided to have one single main.scala.html file that load all the necessary controllers,services,directives, etc from angular using of require.js.
The goal with Angular is to create a single page app and therefore you should avoid to mix it with server side templates.
You must see your main.scala.html template as the entry point of your single page application. There you generate and load all the pieces you need and give the hand to angular to manage the rest.
I agree with Renato. It's probably better to have a single controller and template that sets up the single page app with angular. Then use AJAX to send requests from the browser to other controllers (see http://www.playframework.com/documentation/2.2.x/JavaJsonRequests).
If want to to avoid Scala templates completely, you can put your web pages and javascript in the public directory and only use AJAX.
So I have a project that I am working on and it requires that I use jsPlumb for graphical elements connections and I am building my app entirely using AngularJS.
What is the procedure to follow if I want to include another library's code into my controller (to fire up some jsPlumb code, say on ng-click) or any other part of my AngularJS code? Should I do that or why should I not do that?
Take a look at this well-commented jsPlumb/angularJs integration example:
https://github.com/mrquincle/jsplumb-example
I don't see an easy way to establish two way data binding between Angular and jsPlumb.
What I ended up doing on my project is creating a custom Angular service which serves as a bridge between controllers and jsPlumb. Such service contains methods specific to application, such as:
removeElementFromFlow
addElement
getElements
getConnections
isElementConnected
etc.
It allows to keep all jsPlumb plumbing code outside of controllers, keeping them clean.
JSPlumb has put out a tutorial on how to use JSPlumb with Angular:
https://jsplumbtoolkit.com/docs/toolkit/demo-angular.html
I'm trying to find the way of incorporating AngularJS into existing application. Application is modular, so every module has HTML markup and JS script files. Modules are loaded with requirejs and jQuery (for loading markup).
I would like to use AngularJS features in some of the modules, having in mind the possibility of migrating to AngularJS in future. So ideally I want something like this:
define([ 'angular' ], function (angular) {
return function (element) {
// The "element" parameter contains the reference to
// the detached DOM node that contains the markup.
// And what I think should be done is compiling
// or initializing AngularJS with the given DOM HTML fragment
// and with controller, etc.
angular.doSomething(element, ...something...);
// The application module engine will inject the returned element
// into the DOM tree.
return element;
};
});
Any ideas? Thanks!
Just following the tutorial, specifically Step 2 (http://docs.angularjs.org/tutorial/step_02) will show you how to just do a single controller on the page with some simple functionality.
You can just use this, or you can start expanding it by modularizing it as in Step 7. By creating an module you can then add directives and services and take advantage of all that Angular offers. You don't necessarily need to configure routes or anything, but by creating an app module, you can incorporate other modules or services offered throughout the web or by Angular.
AngularJS isn't designed to really run alongside other frameworks and be used for little bits and pieces. You could hack it together to do this but it'll probably become very messy. Angular is much better suited to becoming the basis of the entire app.
Something like jQuery is great for dropping into an app and adding functionality, but angular is far more complex.
If you do want angular to take control of certain parts though, take a look into the ng-controller directive and how it works. Then in your standard markup you'd just add the ng-controller attribute to any element, and then add a new angular controller to your javascript. It would then manage that DOM element.
Look into angular controllers for more info on that. But as I say, I'd suggest making the app entirely Angular rather than trying to just add angular bits to it