I am coming from a different development background with a very little jQuery and/or shieldUI knowledge. Can someone please very shortly explain how to remove/destroy shieldUI components or widgets? I don't see any special widget method therefore I assume this is done with jQuery. By destroying I mean removing everything down to (including) markup.
Also, what happenes with widget when calling hide()? I see that markup is somehow stripped down (removed), but some wrappers remain. Is it safe to call another widget setup with the same "id" ? will it overwrite? will it cause object orhpans?
As you see I am missing some very basic "how it works". I am a quick learner so please, just few basic pointers will do. Thank you :)
EDIT: found destroy widget method under "swidget()"...what is swidget?
swidget() gives you a reference to the component instance, through which you can access methods and properties, such as height, width, refresh(), destroy(), etc.
Further, with respect to the question at hand, regarding the destroy method and approach - the ideas is, that whenever you need to refresh some data on the component, you can recreate it, rather than calling a method such as rebind.
This is demonstrated in the following demo:
http://demos.shieldui.com/web/rangebar-chart/related-charts
Related
I am just beginning with AngularJS and I am trying to use ng-repeat on the Firebreath plugin and it doesn't seem to work.
<div ng-controller="PluginCtrl">
<object type='application/x-sometype' ng-repeat='plugin in plugins'
id='pluginobj_{{plugin.id}}'>
</object>
</div>
And my controller file has code which looks like:
var app = angular.module("appName");
app.controller("PluginCtrl", function($scope){
$scope.plugins = {};
$scope.plugins["1"] = {id: "1"};
$scope.plugins["2"] = {id: "2"};
});
I know this is an issue with Firebreath's JSAPI because it works really well if I change the object 'type' to something else. I did not go deep down yet on what's the cause of this but I guess some of the object dom properties angularJS needs when computing with ng-repeat is missing in the JSAPI. It would be helpful if someone knows why this is the case or already came across this. Thanks in advance.
Edit: By not working I mean the {{plugin.id}} is not being substituted by the values 1 & 2 from the scope, though two object elements are being created in the dom.
This is actually not JSAPI specifically, it's plugins in general. I doubt that it would work with Flash either. I am not 100% certain of that, but I did at one point spend a day or so trying to fix it and ended up just getting deeper and deeper into some of the weirdest issues I've ever encountered.
The number of reasons why this would be a bad idea is longer than I can even remember, and I wrote FireBreath. Suffice it to say that it is not likely to ever work well to do what you're doing. For one thing, you should never set the type of an object tag before adding it into the DOM because the browser in some cases (depending on browser, OS, and version) will actually reinstantiate the plugin instance when you remove it and add it elsewhere, which angular will tend to do in certain cases.
I really recommend only using a plugin by injecting the html directly in, or, if you won't accept that, setting the type after it's been rendered. You should be able to rig up a directive to make this happen however it needs to, including if necessary adding multiple instances of the plugin.
You are also welcome to spend some time trying to fix it; I have already done so, and I don't consider it worth my time to spend any further time on it.
Being brand new to cytoscape.js, I may be missing something obvious. Please forgive me if that is so.
I am studying the first example offered here:
reached from this page
Three files are offered -- HTML, CSS, JavaScript -- along with the impression that these three will, when loaded into my browser, create a running example.
But the HTML seems to be incomplete, possibly in two ways:
the JavaScript on the jsbin page needs to be included via a script tag
the variable cy is not defined anywhere that I can see, leading to this error message in the console: Object #cy has no method cytoscape
A stack overflow search on that error message points back to the very fine cy.js documentation, but alas, I am still in the dark: where do I initialize the "cy" object?
And best of all, where can I find a complete working example, useful for such a raw beginner as myself, something I can pore over and study until I begin to grasp the logic of this style of programming, and make use of this very fine library?
Thanks!
Your first example is indeed a fully working example. Just use the menu to the top left. Choose File -> Download. This will download a single HTML-file, that works out of the box.
The file is called jsbin.ravecala.1.html. Open with
firefox jsbin.ravecala.1.html
(I also struggled a while before realizing this.)
I really don't know what's your JavaScript & jQuery knowledge level, but it seems you may need to practice it all a little.
Yes, if you're referring to the following tag:
<script src="http://cytoscape.github.io/cytoscape.js/api/cytoscape.js-latest/cytoscape.min.js"></script>
This is indeed necessary, as it is the basis of cytoscape.js, the library itself, wich allows, for instance, add the method cytoscape to the variable #cy, as you mentioned in your second point.
The variable #cy is the div itself. jQuery refers to objects IDs this way, with #. So:
<div id="cy"></div>
Can be referred as $("#cy"). Wich adds the cytoscape function to it is the library itself.
I think that this live example is really good, although the one you linked is more basic and appropriate to get known with the basic structure and initialization of cytoscape.js. I suggest you to get known with jQuery (this course was really clear to me) and read the cytoscape.js documentation, which is full of rich examples.
I've been searching for a while, and I'm pretty confident this is a new question, and not a repeat like the title suggests. :)
Basically, I'm trying to find out if there is a subscribe-able event that KnockoutJS creates after a template render when using something like jQuery templates.
I'd use the built-in "afterRender" but I found out that it doesn't fire if the observable array is cleared. I built this demo to illustrate that problem: http://jsfiddle.net/farina/YWfV8/1/.
Also, I'm aware that I could write a custom handler...but that seems really unnecessary for what I need.
I just want one event that fires after the template finishes rendering.
My colleague actually solved this last night using something we were playing with before I went home.
So the whole "problem" with the events “afterRender”, “afterAdd”, and “beforeRemove” is that they act differently in conjunction with a "foreach" binding. KnockoutJS is nice enough to tell you this on their page, but for whatever reason it didn't actually sink in for me until I saw it in practice.
What really works is to scrap the whole "foreach" binding and use Knockout's native "data" bind like this:
data-bind="template: { name: 'item-template', data: items, afterRender: caller }"
Then "afterRender" works exactly as the name suggests.
I was under the impression that you couldn't iterate the collection and render new UI without foreach, but these examples illustrate that it does work.
http://jsfiddle.net/farina/kuFx2/1/ (Using object array style ViewModel)
http://jsfiddle.net/farina/QtZm2/1/ (Using function style ViewModel)
I made an example for both ViewModel styles because I sometimes need one or the other.
Thanks for the help Dan!!
Is beforeRemove is what you are looking for? I am not sure what behaviour you want to achieve. Please checkout this sample: http://jsfiddle.net/romanych/YWfV8/8/
Is it what you want or not?
A simple javascript widget design question.
I have started working in javascript fairly recently. And as part of my work, I intend to create a lot of reusable code; so for me javascript widgets seems like the best way to go.
However I am faced with a design dilemma, and I am not able to find the right answer.
I have a simple javascript widget, which alters the string in a html component. So my widget is somewhat like this:
(function() {
var convertString = function() {
$(".classForHtmlComponentsIWantToHandle").each(function(index, element) {
//js_fu stuff done with string fetched from "element"
});
};
var _somePrivateHelperMethod() {
//some work that would have been impossible without this helper method
};
GloballyDefinedNamespace.StringUtils = {convert : convertString};
}());
this allows me to call later
GloballyDefinedNamespace.StringUtils.convert();
Now if you would notice in my widget-ish function above, I extract all the HTML components from the DOM, that I want to alter string for. Interesting bit is that HTML will have span and divs with same css class and also textbox components with css class.
Both have a different way of extracting their value and setting new value back.
Based on my experience, if this is a widget to alter string then all it should care about is incoming object that "hold" string in a uniform manner and then based on a object expectations, my widget should be able to operate blindly.
"if it sounds like a duck, walks like a duck, then it's a duck". Kind of thing.
So effectively I would like to be able to NOT worry about distinguishing "element" object being a textbox or span in my widget. Instead wrap it into a generic wrapper.
However people have advised me that in javascript widgets the usual convention is to take care of component specific stuff within widgets. I am not convinced, as I firmly believe in programming to interfaces and not specifics. So I am at conflict.
In my example above, I don't think so the highlighted dilemma does justice to this problem, but on a larger scale this pops up as a question for me often.
I would like to hear opinion from guys, as to how to build that component independence within my widget for an HTML DOM? Is a solution to create javascript wrapper objects with same interface and then css-select them separately and then make method call as following?
(function() {
var locateAllComponents = function() {
$(".generic-class").each(function(index, element) {
//wrap element into suitable wrapper that has common interface for getter
//setter.
GloballyDefinedNamespace.StringUtils.convert(wrappedElement);
});
};
}())
Any insights and answers would be highly appreciated.
You are trying to force concepts on javascript that are foreign to it.
Programming to an interface works for for OOP, but for other language types it is a bad idea.
You can look at how jquery uses .text() (http://api.jquery.com/text/) and .val() (http://api.jquery.com/val/) and you will see that what you want to abstract they put into two different functions, for a reason.
Widgets can be useful, but at a cost of bloat and performance, so you need to look at what you are doing and ensure that you don't exact too much of a price.
So, start small, perhaps with a widget that can work on form elements, and see what you can do reasonably within the object, but you will find that at some point it becomes very helpful if either the API user or the API developer creates functions to pass in to your widget, to get the additional functionality.
But, all of this will impact performance, so as you work, do some unit tests so you can look at changes in performance to help guide you on what changes are worth the price.
You may want to start with looking at the JQuery UI widgets though, and see what they did, rather than just re-inventing the wheel for no reason.
Been working on an App and since it's getting a bit too big I've thinking of ways to improve memory management since the app runs mostly on Javascipt. So every time a navigation item is clicked I would call the jquery empty then show the html via ajax. ex:
//$.ajaxSetup(); called before this
//$this is the attached element
$.ajax({success:function(data){
$this.empty().html(data.output).fadeIn(400);
//more javascript stuff like loading tinymce or jquery ui
}});
is this enough to prevent memory leaks? I'm not entirely sure what empty does but I'm assuming it removes all DOM elements within that div along with any other objects and events? btw. You can find the app here http://webproposalgenerator.com/ and http://webproposalgenerator.com/demo.
any tips on improving the performance/security or any feedback at all would be greatly appreciated.
$.fn.empty should be enough, it deletes all data and events associated to the elements and then deletes the elements. It also calls .widget("destroy") on all jquery-ui widget.js based widgets that are defined on those elements.
It is also important to note that jquery's $.fn.html method calls $.fn.empty() on the given element before appending html, therefore, if you are using $.fn.html, you don't have to call $.fn.empty
actually my guess was that .html implies .empty anyway, also I'm not sure that's true. for the perforamnce part: according to jqfundamentals excelent book it is a recommanded best practice to add content while the element is in .detach() from the DOM. tried to lock at the code for advice but didn't find it. nice site btw