I am working on an assignment for a course in "Coding the Humanities" which involves writing a custom web component. This means I am required to use Polymer even though as far as I can see there is absolutely no added value to doing so.
I want to create a literal chat "room" in which users input a character to identify themselves and can walk around the room bumping into one another after the fashion of robotfindskitten.
My idea was to write each character and its position to a Firebase location, updating everyone's positions in real time, so I need the Firebase JS client- using core-ajax for REST requests isn't fast enough.
The GitHub readme for the core-firebase element consists of a link to a less than helpful component page.
Looking at the core-firebase element itself, I don't see anything that corresponds to the 'value' event; locationChanged has a 'child-added' event handler, but that's it.
Am I crazy for thinking the core-firebase element is just very incomplete? Should I try to write my own 'value' handler? If so, do I just add it to the locationChanged property of the object passed to Polymer()? I'm very confused - I know enough JS that what's happening in the core-firebase code is straddling the limits of my comprehension. (Which might have to do with the this keyword, I don't know.) Any input here would be appreciated. (And yes, I've already remarked to the instructor that I could have handled this using plain old jQuery and Firebase if I didn't have to use Polymer. No word as yet on that.)
Looking at the commits for core-firebase it looks like it's had about two days work on it plus some maintenance, so it wouldn't be surprising if there are missing features.
One nice part about Polymer is that it interops very well with other ways of writing apps. It's totally reasonable and supported to use jQuery and Firebase directly to read from firebase and react to changes. You can still make good use of polymer's templating and databinding by doing this within an element of your own and using Polymer's data binding, templating, and plain old DOM events to propagate those changes throughout your app and render them onto the page.
Related
I'm working on a static site generator where I'd like to be able to support both reactive JavaScript interaction and standard load-a-fresh-page-into-the-browser hyperlinks. It occurred to me that something like Svelte might be a good fit for this; I could use the server-side rendering support to generate HTML for all my pages, and then I could compile and ship JavaScript components with hydratable: true to support the dynamic features.
One issue I thought of with this approach is that most of my project's components will be entirely static content: just HTML and hyperlinks, without any state or event handlers, and I won't change the props except when I generate a new HTML file for a different page. If I naively generate JavaScript to hydrate all those components at page load time, I could end up with a much larger bundle (and more work done at runtime) than I actually need.
Does Svelte offer any way to optimize this situation? Can I somehow check if a component is a pure function of its props so I can avoid hydrating it if I don't need to? Or is the compiler smart enough to do that for me?
This is a good question that we don't currently have a simple answer for.
It is possible to determine whether an individual component has values that can change — svelte.compile(...) returns an object with a vars property, which is an array of all the values inside the component. Inspecting this array will tell you which values are never reassigned to or mutated. (It won't tell you if a component has event handlers that have side-effects but which don't affect state, which would also be necessary to determine whether a component is entirely static. That's information that we could add in a future 3.x release.)
But it's only half the story. Consider a component that declares a name prop...
<script>
export let name;
</script>
<h1>Hello {name}!</h1>
...and which is used in your app like so:
<Greeting name="world"/>
As far as the compiler is concerned when it compiles the <Greeting> component, the name value could change at any moment, so it's unsafe to treat it as entirely static. But if it could understand your app more holistically, it would be able to replace {name} with world, which would have various benefits.
When hydrating, Svelte assumes that there could be a discrepancy between the existing DOM and what's supposed to be there. In many situations it would be safe to assume otherwise, and skip checking subtrees it knew to be static, which would obviate the need to include them in the generated JS.
As a compiler, Svelte is unusually well-positioned to be able to take advantage of these techniques, but it's work that we haven't undertaken yet. Ideally we'll be able to upgrade the compiler in such a way that your apps will get smaller without anything needing to change. If you're keen to start experimenting with what's possible in the meantime, then the vars property returned from svelte.compile(...) (and also the ast property, I suppose) is the place to start.
The most confusing thing in this API is for me the reason why use it. I know ReactJS and RxJS and I'm used to the concept when view reacts to data change. So watching changes to DOM, which happens definitely after some mutations to data, I can't see much sense in it. So my question is when (not) use it?
You're thinking of the problem with a situation where you are already one step ahead. If you are using React/RxJS then the actual value of MutationObserver will most likely be very small.
Even within this, however, there is a clear possibility to leverage this. Suppose you are attempting to use a library within your React application that is not explicitly built for it, and modifies the DOM in some way, but want to extend this further or capture something from it. The best example for this would be augmenting FancyGrid further.
Currently, in a component, you would invoke such a library in componentDidMount, the same way the component above is built. However, this is simply fire-and-forget - you don't know when it is done executing, you don't even know what is happening on the "outside".
Enter MutationObserver. With it, before binding such a library to an element, you can use an observer to be notified of when elements are created, track them, and track property changes. The simplest use case for this would be to make a spinner above a (particularly time-consuming on load) grid.
Using angular brings lot of weird style of code. For example I always thought that this
<button onclick="myFunction()">Click me</button>
style I should not ever use, except when I would be lazy and want quick and dirty code. And I never used such style in projects and also I even thinked that this is bad.
Now when I see angular
here is the example:
<div enter="loadMoreTweets()">Roll over to load more tweets</div>
which is from there
http://www.thinkster.io/pick/IgQdYAAt9V/angularjs-directives-talking-to-controllers
which is good style by the tutorial. I dont get it. So then it means earlier example with onclick is also perfectly good? Then why nobody uses it at least these days when people use lot of jquery for example?
Let me cite from a book Angular, by Brad Green & Shyam Seshardi
Chapter 2 ... A Few Words on Unobtrusive JavaScript
The idea of unobtrusive JavaScript has been interpreted many ways, but the rationale
for this style of coding is something along the following lines:
Not everyone’s browser supports JavaScript. Let everyone see all of your content and use your app without needing to execute code in the
browser.
Some folks use browsers that work differently. Visually impaired folks who use screen-readers and some mobile phone users can’t use
sites with JavaScript.
Javascript works differently across different platforms. IE is usually the culprit here. You need to put in different event-handling
code depending on the browser.
These event handlers reference functions in the global namespace. It will cause you headaches when you try to integrate other libraries
with functions of the same names.
These event handlers combine structure and behavior. This makes your code more difficult to maintain, extend, and understand.
In most ways, life was better when you wrote JavaScript in this style.
One thing that was not better, however, was code complexity and
readability. Instead of declaring your event handler actions with the
element they act on, you usually had to assign IDs to these elements,
get a reference to the element, and set up event handlers with
callbacks...
...
In Angular, we decided to reexamine the problem.
The world has changed since these concepts were born...
... for most inline event handlers Angular has an equivalent in the form of
ng-eventhandler="expression" where eventhandler would be replaced by
click, mousedown, change, and so on. If you want to get notified when
a user clicks on an element, you simply use the ng-click directive
like this:
<div ng-click="doSomething()">...</div>
Is your brain saying “No, no, no! Bad, bad, bad!”? The good news is
that you can relax.
These directives differ from their event handler predecessors in that
they:
Behave the same in every browser. Angular takes care of the differences for you.
Do not operate on the global namespace. The expressions you specify can
To get more details, read the book: http://www.amazon.com/AngularJS-Brad-Green/dp/1449344852
EXTEND
Following the discussion in comments, I would like to add a more explanation.
As stated here: Wikipedia - AngularJS:
Angular is a framework, which goal is to augment browser-based applications with model–view–controller (MVC) capability, in an effort to make both development and testing easier
The Model–view–controller, a short extract from wikipedia:
A controller can send commands to the model to update the model's state (e.g., editing a document). It can also send commands to its associated view to change the view's presentation of the model (e.g., by scrolling through a document).
A model notifies its associated views and controllers when there has been a change in its state. This notification allows views to update their presentation, and the controllers to change the available set of commands. In some cases an MVC implementation might instead be "passive," so that other components must poll the model for updates rather than being notified.
A view is told by the controller all the information it needs for generating an output representation to the user. It can also provide generic mechanisms to inform the controller of user input.
Summary:
The most important part here, is the fact, that View can publish the Controllers actions to the user. And this is exactly what the Function calls in HTML do represent.
This is a misunderstanding:
Using angular brings lot of weird style of code. For example I always thought that this
<button onclick="myFunction()">Click me</button>
style I should not ever use, except when I would be lazy and want quick and dirty code. And I never used such style in projects and also I even thinked that this is bad.
It is perfectly valid to use that style of code if you can decide what event handler to attach to the button when you render the HTML code. With jQuery we see many dynamically attached event handlers because many times the elements themselves are dynamically inserted or whether to attach an event listener or what to attach is dynamically decided.
I know enough jQuery/JavaScript to be dangerous. I have a JSON array that I'm interacting with using two different elements (a calendar and a table, to be precise). Is there an event handler (or any other way) I could bind to so that the table would refresh when the JSON changes?
Basic programming, parse the json (=string) into a javascript object or array. (you probably have already done that.) Use an implementation of the observer patern.
I suggest taking a good look at #Adam Merrifield 's interesting links.
Most of the time using getters and setter where you can fire a custom event (or call a callback method) inside a setter is the key in this.
KnockoutJS is a good framework to help you do such binding. It also uses the observable - observer/subscriber pattern.
using timers is not a really good idea.. little to much overhead. (doing stuff also when nothing gets changed. And you will always hop x ms behind (depending on the polling frequency).
You might want to consider Knockout.JS
It allows bi-directional mapping, so a change to your model should reflect on your view and vice/versa.
http://knockoutjs.com/documentation/json-data.html
However, it might be late stages of your dev cycle, but something to consider.
For a Greasemonkey script running on twitter.com, I need to access the twttr.streams.TweetStream instance of the main timeline (dubbed 'Home' internally) programmatically. I'm using Firebug and Javascript Deminifier to bring their JS code into a readable form. That way, I could previously work out that I could access it via twttr.app.currentPage().streamManager.streams.current in my GM script.
This has worked perfectly over the last months. Today, Twitter seems to have changed their code, breaking my approach (not their fault, obviously ;)).
I can still get to the current page via twttr.app.currentPage(). However, it doesn't have a streamManager field anymore.
I've tried various paths to get there, but all were dead ends. Unfortunately, I don't completely understand the class system they are using yet. It seems like the streamManager property is still there -- on a mixin called mixins/streamablePage, which should be provided by the class twttr.components.pages.Home. I can't figure out how to access it, though. (Or if the class system hides it in some impenetrable way.) That mixin also provides a getStreamManager() method, but I can't access that either, e.g. via twttr.app.currentPage().getStreamManager(). Is there any trick I need to perform to get access to these mixins from the outside?
Can anyone spot an alternative method to get to this instance? Note that I need the original instance used on the timeline page. Yes, I could easily create a new instance via new twttr.streams.TweetStream(), but I'm trying to hook into the original events.
I am perfectly aware that this use case is as unsupported as it gets, that's why I'm asking you, not them. :) For the record, I'm not attempting to do anything evil, just providing additional functionality for myself.
Until they change it again, twttr.app.currentPage()._instance.getStreamManager()