view javascript object change using BackBone - javascript

I have an object:
NAMESPACE.SOMEOBJECT.VALUE = 0
Some other foreign script owns and changes that value based on an event that I don't have access to. I know that the value is changed by different events on different pages. I can't edit the .js that controls that object. Does anyone have any idea how i can listen to that specific object and then run a function if that value changes?
I cannot add a new library or any external script. I'm using Backbone, require.js and jQuery.
If I were to use a backbone.model and add a reference to this object in my model, and then in my view I were to listenTo my model, would that tell me if that object has been updated? If so, sow would I go about doing this?
I DO have access to an ID on the page that allows me to access a DIV that has the value that I'm looking for. Keep in mind, that every time my object value updates, I need to know if it's been updated.

Unfortunately there's no way to 'add a reference to this object in the model' as this is just another way of saying that something should 'listen' for changes on the object. In order for a model to trigger a change event, one of its attributes has to change and this cannot happen by any means other than calling the model's set method or (re-)fetching (changed) data from the server-side.
How about polling the object instead of listening for an event? You could use setInterval to periodically query the relevant value and track its changes. In the event that the value has changed you can invoke the desired behaviour.
You could also wrap this functionality in a Backbone model if this is a good fit for your app's design: In the model's initialize / constructor use setInterval to start polling the value periodically and use set to copy it onto one of the model's attributes. Backbone will take care of tracking state for you and the model will trigger a change event if (and only if) the value changes.
Hope this helps.

Related

Changes-aware list in angularjs

I'm doing some work on existing angularjs code, and I have something of that sort: I have a list of objects on the client side, which I transfer via a put request to a server side.
The existing code simply takes the list of objects in the $scope and puts it in the json as is.
I want to implement a mechanism where only the objects that have been changed since some event would be sent.
I can do that hardcodedly and save another list of objects and clear it when I submit the changes, but I want something cleaner - f.e, a Changes aware list,
Then, I could do something in the sort of list.changedObjects.
I couldn't seem to find anything like that from basic research, so I was hoping you guys would know something about it.
I feel this is a use-case of Observer pattern. https://github.com/melanke/Watch.JS has an lib/example to observe changes in javascript object. Then you can trigger an event in Angular to do your job accordingly
http://jsfiddle.net/2zT4C/23/
$watch helps to listen for $scope changes
AngularJS can then check the value returned against the value the watch function returned the last time. That way AngularJS can determine if the value has changed.
$scope.$watch('list', $scope.sendNewList, true);
it will will update innerHtml if new value of object is not equal to old value of object i.e if it has been changed.
For detailed info check this - $watch() or $watch
AngularJS watch array of objects for data change

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).

Ember.js - view's model observer fires twice

I want to run some view code when the model that the view is bound to changes.
My view has an observer on the controller model, like so:
App.SomeView = Em.View.extend
modelDidChange: (()->
# do stuff
).observes('controller.model')
When the model changes, modelDidChange is called twice.
Why is that?
Is there a better/different way to achieve what I'm trying to do here?
Using Ember 1.3.0.
Are you sure that your view needs to know when the model changes? The view's template gets its properties from the controller, and should update automatically when they change. You certainly want to avoid any observers if you can.
But I don't know much about your use case, so assuming that it's necessary, I would try a debouncer. It's likely that the model isn't changed twice, the event is just fired twice. Ember has a LOT of action that happens in between user hooks, so the model is probably just set to the same value twice. Use a debouncer to have your method called just once.
Ember.beginPropertyChanges();
# model updates
Ember.endPropertyChanges();
The first time it fires because you made a change in your browser and that change gets sent to the Ember data store which triggers the observer callback. The store then makes an update request to the backend which responds with an updated model, when the store receives this updated model it triggers the observer callback once again.

Using jQuery UI drag/drop with backbone.js

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.

Instant update backend with Knockoutjs

I am trying to create a web page with form that once user change any field, the validation and update commit immediately rather than letting user to click on submit button. I am using Knockout.js and mapping plugin. I know I can achieve this by creating a computed field for each original fields, but this kind of work is tedius and dumb, is there good practice to create a general listener to listen on any changes in any fields and update backend respectively?
In order to subscribe to any change you could use ko.toJS() method. Actually it allows to walk through object graph and unwrap observables. As your probably know when you use ko.computed it subscribes to all reads of observables fields and re-evaluate on every change. So if you use code like this:
ko.computed(function() {
ko.toJS(viewModel);
// update data on server
});
Also you should pay attention that this piece of code will update data on server right after initialization. It could be easily avoided. Please checkout this example: http://jsfiddle.net/UAxXa/embedded/result/
Also I think you might want to send only changed data to server. You could incorporate ko.editbales plugin ( https://github.com/romanych/ko.editables ) and some KO under-hood knowledge. Please checkout this sample: http://jsfiddle.net/romanych/RKn5k/
I hope it could help you.
You've got several options but if you want a single listener, one good way is to use the same code I used to create a change tracker. It simply listens for the observable changes. Its about 19 lines of code. You can grab this and instead of using it for change tracking, just wire in a method that saves the changes when they occur.
NuGet http://nuget.org/packages/Knockout.ChangeTracker
Codeplex http://kochangetracker.codeplex.com/
To Setup change tracking, add this tracker property to your view model:
viewModel.tracker = new ChangeTracker(viewModel);
Hook these into your view to determine when changes occur:
viewModel.tracker().somethingHasChanged();
Hook this into your view model when you want to reset state in functions (ex: load, save):
viewModel.tracker().markCurrentStateAsClean;
Optionally, you can pass your own hashFunction for state tracking, too.

Categories