EmberJS - Adding a binding after creation of object - javascript

I am trying to bind a property of an object to a property that's bound in an ArrayController. I want all of this to occur after the object has already been created and added to the ArrayController.
Here is a fiddle with a simplified example of what I'm trying to achieve.
I am wondering if I'm having problems with scope - I've already tried to bind to the global path (i.e. 'App.objectTwoController.objectOne.param3') to set the binding to. I've also tried to bind directly to the objectOneController (which is not what I want to do, but tried it just to see if it worked) and that still didn't work.
Any ideas on what I'm doing incorrectly? Thanks in advance for taking the time to look at this post.

So in the example below (I simplified it a little bit, but same principles apply)... The method below ends up looking for "objectOne" on "objectTwo" instead of on the "objectTwoController".
var objectTwoController: Em.Object.create({
objectOneBinding: 'App.objectOne',
objectTwoBinding: 'App.objectTwo',
_onSomething: function() {
var objectTwo = this.get('objectTwo');
objectTwo.bind('param2', Em.Binding.from('objectOne.param3'));
}.observes('something')
});
The problem is that you can't bind between two none relative objects. If you look in the "connect" method in ember you will see that it only takes one reference object (this) in which to observe both paths (this is true for 9.8.1 from your example and the ember-pre-1.0 release).
You have few options (that I can think of at least).
First: You can tell the objects about each other and in turn the relative paths will start working. This will actually give "objectTwo" an object to reference when binding paths.
....
objectTwo.set('objectOne', this.get('objectOne');
....
Second: You could add your own observer/computed property that will just keep the two in sync (but it is a little more verbose). You might be able to pull off something really slick but it maybe difficult. Even go so far as writing your own binding (like Transforms) to allow you to bind two non-related objects as long as you have paths to both.
_param3: function(){
this.setPath('objectTwo.param2', this.getPath('objectOne.param3');
}.observes('objectOne.param3')
You can make these dynamically and not need to pre-define them...
Third: Simply make them global paths; "App.objectOneController.content.param3" should work as your binding "_from" path (but not sure how much this helps you in your real application, because with larger applications I personally don't like everything global).
EDIT: When setting the full paths. Make sure you wait until end of the current cycle before fetching the value because bindings don't always update until everything is flushed. Meaning, your alert message needs to be wrapped in Ember.run.next or you will not see the change.

Related

How should I use Variables and jQuery Dom navigation?

I was just wondering which is the correct or most efficient way of navigating through the Dom using variables.
For example, can I concatenate selectors
var $container = '.my-container';
$($container).addClass('hidden');
$($container + ' .button').on('click', function(){
//something here
});
or should I use the jQuery traversal functions
var $container = $('.my-container');
$container.addClass('hidden');
$container.children('.button').on('click', function(){
//something here
});
Is there a different approach, is one best, or can you use them at different times?
The $ is usually used only when working with an actual jquery object. You generally shouldn't prefix anything with that unless it's really something from jquery.
Beyond that little bit though, performance-wise, your second bit of code is going to be faster. I made an example jsperf here: http://jsperf.com/test-jquery-select
The reason the second bit of code is faster is because (if I remember correctly) jquery caches the selection, and then any actions performed on that selection are scoped. When you use .find (which is really what you meant in your code, not .children), instead of trying to find elements through the entire document, it only tries to find them within the scope of whatever my-container is.
The time when you wouldn't want to use the second pattern is when you expect the dom to change frequently. Using a previous selection of items, while efficient, is potentially a problem if more buttons are added or removed. Granted, this isn't a problem if you're simply chaining up a few actions on an item, then discarding the selection anyway.
Besides all of that, who really wants to continuously type $(...). It's awkward.

PhysicsJs - how to remove a world behavior, "constant-acceration' after it has been added

My behaviors on initialization are added as follows:
world.add([
Physics.behavior('interactive', { el: renderer.el }),
Physics.behavior('constant-acceleration'),
Physics.behavior('body-impulse-response'),
Physics.behavior('sweep-prune'),
edgeBounce
]);
I'd like to, at a later time, remove the "constant-acceleration" behavior. I read a couple of posts that said to use the remove() method but I'm not getting anything to happen using it like follows:
world.remove( Physics.behavior('constant-acceleration') );
Can anyone advise how I could achieve removing a specific behavior from the world after it has been added?
The Physics.behavior docs indicate that a Behavior object is returned when you call Physics.behavior (because it constructs a new one). So you need to keep a reference to the Behavior object you'd get back from the call you've put into your world.add array, then pass that reference to world.remove later. As it is now, you're making a new Behavior (separate from the one you made first) and immediately passing that brand new object to world.remove, which will basically do nothing.

JavaScript to jQuery for KendoUI

I've been using KendoUI and have been using they're command functions. However to call JS I must call named jS functions. No huge deal. When I use the "This" key word it brings back the entire grid and I mus find a value of a child from a sibling of the same parent elements and i wound up doing this ugly thing. The question I have is how can I turn this "thing" into something jqueryable readable and comprehensible
function AddRole(e) {
var $ParentNode = e.target.parentNode.parentNode.children[1].children[0].getAttribute("value", 0);
}
Sorry, but you have other problems.
If you rely on such a structure e.target.parentNode.parentNode.children[1].children[0], your Markup and JS do not scale at all.
Use the oppurtunity to create scalable and consistent code. Or at least, set some id, class or html5 data attribute on the children[0] element in order to identify it properly.

JS Prototype: Avoiding an event handler being bound several times to the same object

So with the new ajax things we have to reinitialize our Javascript event handlers every time an ajax call is made, since an ajax call can result in pretty heavy redrawing of the whole page resulting in uninitialized objects.
Have a look at this jsfiddle:
Javascript eventhandler added multiple times to the same object
This is what I have and it seems to work, but since it is going to be used with everything we have: I wanna make sure that it is the right solution.
E.g. the global defined variable
MyCompany.field.bindedOnfocusSelector = MyCompany.field._focusEventHandler.bindAsEventListener(MyCompany.field);
just feels wrong. And it lacks the possibility to hand more function arguments.
As another poster suggested the prototype $(smth).on(event) I have problems to get it working - I remember problems crossbrowser wise (e.g. on IE 8 things didn't work which worked in Firefox) and even in this simpler example jsFiddle problem with on('focus'):
How about you register an ajax responder, and add the methods after a request has completed
Ajax.Responders.register({
onComplete: function(transport) {
MyCompany.field._initTextInputFields();
}
});
UPDATE
Ok, taking into consideration your comment, how about observing the whole page i.e. body and determining if a input event occurred, ex:
$("#body").on("focus", "input[type=text]:not([readonly])", function(event, element) {
// ....
});
I think this will help you as you only add one observer, and never need to remove it, all your logic can be contained.
PS: note that Event.on is only available in prototype 1.7
UPDATE
ok, what if you just check the click, keyboard won't work now though but i think this is a viable solution
Updated Fiddle

Override "private" function in JavaScript

I'm monkey-patching some of the jQuery's Draggable code*.
The goal is to avoid modifying the original source files and patch dynamically one of the internal functions.
The function _generatePosition is declared like this:
(function($) {
$.widget("ui.draggable", $.ui.mouse, {
...
_generatePosition: function(event) {
...
}
}
})(jQuery);
Is it possible to achieve the dynamic replacement of it?
*So it calculates the snapping grid relative to the top of parent element and not relative to the top of element being dragged. See here for more details.
You can manipulate individual instances:
.draggable().data("draggable")._generatePosition = function() {};
Or modify the prototype, affecting all instances:
$.ui.draggable.prototype._generatePosition = function() {};
You can actually modify these, but only on a per-element basic as far as I know. But you could easily create your own $.fn.draggable wrapper, and just call the original wrapper and run this: draggableElement.data('draggable')._generatePosition = fn
As Jörn Zaefferer pointed out, you could also modify the draggable prototype, by using $.ui.draggable.prototype._generatePosition = fn
Edit for below comments: It seems you can edit these (after the last widget re-write), but I would still steer clear. Here's an example of the base method, you can modify from there if you wish, but keep in mind this can and probably will break in a future release. Also any "inheritors" of the widget won't pick up these changes, not sure if that's an issue.
As for the reason, to deny you access isn't the reason really (not in this case). In library cases like this it's more to be clean than deny you access, or because the library may want to change architecture later, and still break as few people as possible when they do so...letting you only access the "public" members of their code gives the authors more flexibility in changing anything that's "private".
Case in point: jQuery UI 1.8 moved a lot of code into the position utility, allowing a lot of private code cleanup that you didn't see happen, since it was all private before this allowed a fairly big optimization/code reduction without breaking people left and right.

Categories

Resources