Using jQuery UI drag/drop with backbone.js - javascript

One feature of my Backbone app involves associating models of type A with models of type B, which is done by dragging view A onto view B. In B's view class I listen for the drop event and from this I get the DOM element of view A, but no information about model A.
What's the best way to go about retrieving this information? My best guesses so far are
have model A save a reference to itself in the app's namespace, removing this reference on drag end if the drop handler hasn't already done so
fire an event on view A, passing a reference to model B along with the event, and then having model A call a method of model B...
store model A as a $.data attribute of view A
but all these approaches seem convoluted/inelegant.

Storing as a data-attribute is actually quite clean, and the performance will not be bad. You can store the model's cid attribute as data-cid on the DOM el, and use the collection's getByCid method to retrieve the model.

I think the cleanest way to go about it is as kinakuta mentioned in a comment to associate a dom element with the model using the id in e.g. a data-attribute.
This makes sense from an implementation point of view because it allows you to have a bidirectional dependency and you can reference one from the other easily later on when your application beccomes more complex.
Your mentioned solutions would work as well, however, I feel Solution A seems a little hackish, Solution B is less clean code wise and Solution C is essentially the same as using a data-attribute.

Related

Why methods enumNodeFragments undefined?

I am working on a project in which we load two models. Loaded two models opened in the same viewer. At the moment I am looking for a way to establish transparency or hide elements.
For some reason, the hide and isolate methods work on one model, although I am passing the dbId elements of the two models.
I was advised to use the enumNodeFragments method, but in my case it is always undefined, it simply does not exist. I've tried a lot of options, so that this method has appeared, but it was all in vain.
I would like to ask for advice on how I can find this method.
By the way, let me say that for me the most important thing is to find a way to hide the elements of the two models.
Like we discussed in the other thread this method is only available after the geometry data of the model is loaded - Viewer needs to tell whether the model is suitable for node fragment enumeration before it exposes the method:
viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT,()=> viewer.model.getData().instanceTree.enumNodeFragments(dbid, fragId => console.log(fragId)))
See live code here.

Binding to global variables in Polymer

I am fairly new to Polymer, and only just studied how data binding works. I am porting an existing Dojo application, where there would be:
1) A single store (holding data) for each URL
2) A message from the server when a store element was updated
As a result, a dynamically made select box which depended on data in the store would automagically have an extra item if anywhere in the application a user added an item to the store (which held the data)
I am trying to replicate something like this in Polymer.
Use case: imagine an URL like this: /app/categories. By querying it with an HTTP GET, you end up with a JSON of all the categories available. While the app is running, the server might notify of a new element in /app/categories. as a result, all of the selects in the application would then have the extra item automagically.
In Polymer, I learned how to bind a property in the current element to a property in a contained element. I understand how this happens with the right events being fired etc. So, the idea would be to create a select where the items are generated by a dom-repeat, which would be bound to... a somehow global variable (?).
But... is it even possible to bind the property of a contained element to a "global" variable, rather than a property of the containing element?
OR, more broadly, is there a pattern (or even an established pattern) to make sure that when a global variable is changed (thanks to a comet message, or whatever), a bunch of elements binding to it will be notified and therefore changed (in this case, the "select" using dom-repeat to show the items!)
Here is a JSBin that shows how to create a menu via iron-ajax At this point what's missing to the JSBin is the simulation of a server push about a data change, as well as a way to have all of the menus update at the same time.
IMHO the most sane and maintainable pattern is a one way data flow approach (something along the lines of Flux or Redux (which is a bit simpler).
There is one global state object that exists as as a graph structure and the data flows down your component tree (starting with the root component).
Each component has well defined input properties and receives data from the parent component (using data-binding) and passes on parts of the data to its children. When a component changes state, it fires an event which bubbles up the component tree up to your root component that can then update your global state object (which again flows down your component tree), communicate with the backend, etc.
I can also recommend this video from the Polymer 2015 summit, which explains a similar approach (mediator pattern).

Tool to see object references

Is there a tool for Node.js or the browser whereby I can find out which objects hold a reference to object X?
Right now I am using Backbone for front-end development and even though I remove views there still seem to be references to them afterwards.
The reason I suspect this behavior in the first place is because I am using plugin/addons for Backbone debugging in Chrome and Mozilla.
This does make me wonder if perhaps these programs themselves are the ones holding references to the Backbone objects!
First of all,Sadly there is no way to do that.
You can check who calls a function and object which specific variable holds as reference though.
It's not because of Backbone/Node.js but Javascript itself.
When you substitute object/Array, javascript only passes target memory address to the variable.
But I assume it's highly possible that the reason why you are having memory leak problem is not because of references from another variables but event handlers which is often seen in Backbone uses(also knowns as "zombie view")
Once you set events handler in a View, You need to make sure all events are unset before you actually delete the view(.remove()) unless You are using only listenTo for Backbone events and this.$el for jQuery events.
Because events set via listenTo and this.$el are automatically removed by Backbone Core when you remove a View.
And events set by Model.on or global jQuery$ would not be so.
So Please check your whole code whether You are using .on or global jQuery Object to set events, in the case You have, replace them into listenTo or this.$el.on or manually unset them Before You remove them.

Backbone Design - Multiple Views, Same Model, separation of events

I am quite experienced with JS and Backbone, but want your help brainstorming a best practise solution to the following problem:
There are two views. They sit side-by-side running concurrently in the page.
Both of these views are passed the same instance of a model.
Both of these views have actions which can update the model.
How, using Backbone's event driven programming, do you think would be the best way of distinguishing the events fired from view to view.
A possible scenario could be:
The user performs an action which updates the model in an invalid way on View A. But as the user did not perform it on View B they should not be notified there.
You can use intermediary objects to manage the flow between a repository (the object where the connection to the database takes place) and the instantiation / manipulation of views.
Instead of binding a model to a view from within the view, you can let the intermediary object (general purpose controller) make verifications, if required manipulations, before re-rendering the view with the modified model or collection.
Through the use of an event aggregator, you can trigger events from views from within the view, and listen to the event from within the "controller" object, who will in turn perform the required custom actions.
Using custom events seems simple enough. Just treat each view's actions as if they were different and name the events differently for each view (example this.trigger('view1:event1'), this.trigger('view2:event2')).
Make sure the views are subscribed to these specific custom events to avoid collisions on actions that would trigger events on both views (like attribute updates).

Any pointers on cleaner way to maintain state accross view in backbone.js application

I have two dropdowns in a view along with some links. If I change values in a dropdown, data gets refreshed in the view. I need to maintain the changed state of the dropdowns to the next view.
Any recommended way of doing this?
Is maintaining state really the way applications are written in backbone?
As is being advised in the comments, backbone.js would have you manage your data in models outside of the view. You still have data in the DOM, but you serialize it into data managed by a model.
In your particular case, it sounds like you may have one underlying model which is used by two views. Your first view probably needs to register a function for a DOM event triggered when the drop down changes. This function then updates the underlying model. If you other view is on the page and if it has registered to listen for the model's 'change' events then it can refresh itself. Whether it does or not, the underlying model should have the same data.
I think the best advice to give you is to re-read the backbone.js documentation and carefully go through any examples that they give or that you can find otherwise.

Categories