I'm trying to play around with a backbone app that was made with an older version of underscore (1.2.0) inside a newer rails app that has a more recent version of underscore loaded (the underscore that comes with the current version of backbone-on-rails gem), so this is a backwards compatibility issue, which I can't figure out even with the help of the changelog http://underscorejs.org/#changelog, however, it's happening when I'm trying to save data.
Context:
A Company, created by the Companies collection, is trying to save (with the setBucket function) the id of the Bucket it is contained in (see code below).
This is the error I get when I try to save data.
Error
<error>
_.extend
_.clone
_.extend.toJSON
_.extend.save
_.extend.update
Backbone.sync
_.extend.sync
_.extend.save
window.Company.Backbone.Model.extend.setBucket
window.AppView.Backbone.View.extend.createCompanyOnEnter
jQuery.event.dispatch
elemData.handle.eventHandle
Source Code
...(code ommitted)...
var company = Companies.create({text: text}); #this works. company is created
company.setBucket(initialBucket.id); #this triggers the error
....(code ommitted)
setBucket: function(bucketId) {
this.save({bucket: bucketId}, {silent: true}); #the function that's not working
You can run two versions of Underscore simultaneously. Simply load your version of Underscore on the page first, then add this line:
var underscore = _.noConflict();
to alias your version of Underscore to the underscore variable (you can of course use a different alias if you prefer). Then run a find/replace on all of your existing Underscore-using code to replace "_" with "underscore" (or your alias).
Finally, load your Rails app and it version of Underscore to the page. It will get the _ alias, and your code can use its version without impacting your library's version.
* EDIT *
Ok, here's a little more background. In Javascript (just as in Ruby I believe) functions are first-class objects. This means that _ isn't technically the Underscore function itself, it's just a variable that points to the "true" Underscore function (which is itself an object). This also means that you can make aliases to functions the same way you do with any other variable. Just as you can do: var a = 5; var b = a you can also do var b = _; and then you could do b.map() or whatever. Well, almost; because Underscore keeps an internal reference to Underscore, you need to update it, which is where noConflict comes in; that code really should have been: var b = _.noConflict();
By the way, it also means you can go the other direction and change _, if you want: _ = alert; _('hello world').
So, what's currently happening with you is that you bring in Underscore on to your page. Presumably you're doing this by putting an <script src='underscore.js'></script> in your main html.erb file. This brings in Underscore version #1. Then you load your Rails app; I'm not sure exactly how this is working, as it depends on your app, but somehow that app is putting another script tag on the page, pointing to Underscore version #2.
This is a problem, because Underscore version #2 just replaced your version #1 (the same way I replaced _ with alert just now). This breaks your code. You could fix it by just adding your <script> tag after the one from your Rails app. This would restore version #1 and fix your code ... but break your app's code.
What you really want is for your code to use version #1 and your app's code to use version #2. Which is where my original answer comes in: by re-aliasing version #1 of _ to underscore (or anything else), your Rails app can keep referencing version #2 as _, and your code can keep using version #1 as underscore.
Related
Im attempting to update an old version of the selenium-tcl package to work with the new W3C WebDriver (or Selenium 4.0).
Original packages uses a few mixins for the webdriver class.
So I modeled what I saw and created a mixin file named mixin_action_chains.tcl [1] which has a mixin class called Mixin_Action_Chains.
Whenever I attempt to use it I get the error:
% package require selenium
::selenium::Mixin_Action_Chains does not refer to an object
Im not sure why I've modeled it pretty much exactly as I have seen in the other files such as mixin_for_scrolling.tcl [2]* file. What am I missing.
Here is the entire GitHub Repo
Im not sure what else must be done for TclOO. Any thoughts.
Thanks
Im not sure what else must be done for TclOO. Any thoughts.
Update
pkgIndex.tcl: The placement of the mixin-defining script mixin_action_chains.tcl is wrong, it comes after the mixin has already been required in the previously sourced script webdriver.tcl, like entering directly:
% oo::class create C {
mixin ::not::defined
}
::not::defined does not refer to an object
You need to change the order of source command calls in the package ifneeded script.
For the records
Still, in the original version, there were unbalanced curly braces and brackets in your script, which broke sourcing of the file for me:
https://github.com/SavSanta/w3cselenium-tcl/pull/1
I'm trying to deploy a meanjs project but can't seem to figure out how to minify,concat&uglify the project using grunt.
What I've found out so far :
Need to run concat -> ngAnnotate -> uglify (else code won't run)
need to concat in dependency order (else it won't run)
With this logic I've managed to create a single 'uglified' version of the relevant 3rd party libraries (node modules), but I'm unable to do the same for the modules I've written.
I've tried using concat tools that are supposed to reorder the files according to dependencies (grunt-concat-in-order, grunt-concat-dependencies, grunt-concat-deps) but nothing helped. Just errors of missing modules/declarations.
I've tried reordering the js files that should be concatenated, and each time something else is missing and the site loads partially (at best).
reordering the files according to the order they appear in the compiled header doesn't help.
Is there something that concats Angular files according to their dependencies or or a general logic in which I should reorder them?
Thanks.
FOUND IT!
apparently JS and Angular are flexible with missing ';' in the end of module/directive declarations.
I've went through the entire code and added missing ';' in the appropriate places.
For example:
angular.module('core').filter('xyz', [function() {
.....
}])
Finally can go to sleep.
*original post:
Angular module().factory() is not a function after concat (gulp) (cheers to Max Yari)
The first thing to check is that you actually use the DI pattern everywhere in your code as the function parameters will be replaced during uglification and thus won't be resolved let anymore.
ControllerName.$inject = ['component']
Or
angular.module('module')
.controller(['module', function (module) { /*... */}) ;
When you've done that, check if you may explicitly specify file order like this (pseudo code):
['module1_decl_file.js','module2_decl_file.js', '*.js','**/*.js']
I`ve just updated my GAE Go SDK to the newest release. I ran the gofix
on my code, but there were still some errors. The code used to look:
AnkietaTemp = template.New(nil)
err := AnkietaTemp.ParseFile("ankieta/ankieta.html")
but now passing nil doesn't seem to work, so I replaced it into:
AnkietaTemp = template.New("")
_, err := AnkietaTemp.ParseFile("ankieta/ankieta.html")
Tried running my app, but in HTML source I get:
<td width="400"><img src="images/{.section One}{#}{.end}"
alt="images/{.section One}{#}{.end}" width="100%"/></td>
Instead of a neat reference to an image file.
What is the proper way to parse the template files now, after the
update?
In the new template package the template tag syntax changed, as you can see in the documentation. E.g. dot (.) is used instead of # for referencing the "current" item and the template tags are indicated with two curly braces instead of one.
Edit: Oh, and there's no .section tag any more. You didn't provide the structure you pass to template's Execute() method so I can't provide details on how mitigate that exactly, but I guess you can use {{with}} tag like {{with One}}{.}{{end}} or maybe {{.One}}.
I would like to translate my ExtJS application in different languages. My issue is that I'm using ExtJS MVC framework, and most of my JS files are downloaded dynamically by the framework itself.
The ideal solution (that I thought of) would be to have an extra option in the Ext.Loader (or in my Ext.app.Application) that would define the language to use, and depending on this to automatically download such file as "a.MyClass.fr.js" after loading my "a.MyClass.js" (which would contain an Ext.apply, overriding my string resources). That's probably not available in the ExtJS framework at the moment.
The alternative solution I can see, is to perform a trick on the server-side. First, a cookie would be created on the client, to set to the language. On the server-side, I could catch all the requests to JS files, then if a cookie is set (='fr' for example), I'd combine the requested JS file (MyClass.js) with its i18n's friend (MyClass.fr.js) dynamically on the server and return the result. That would work, but it's really tricky because it implies other things (caching...).
Maybe the best way is to implement the first behavior I described in the ExtJS framework myself...
What do you think? I'm looking for a really clean and neat way of doing it! Thanks :)
I recently struggled with the same problem.
Finding a clean way to do this was quite a challenge - most alternatives were either..
1) Duplicate your code base per locale (WTH)
2) Download localized files overriding each of your components (Maintenance hell? What about the poor translators?)
3) Use/generate a static file containing translations and refer to it (All languages are downloaded? Extra build step to generate it? How do you keep them in synch?)
I tried to get the best of all worlds and ended up with a utility class responsible for:
1) Loading the ExtJS translation files (which basically apply overrides to extjs base components)
2) Loading a locale specific property resourcebundle (specifying which locale to load) from the server.
3) Prototyping String with a translate() method which queries the loaded store (containing the message bundle from the server) and returns the translation based on the value of the string.
This is the gist of things:
Bundle & prototyping:
localeStore.load({
callback : function(records, operation, success) {
// Define translation function (NB! Must be defined before any components which want to use it.)
function translate() {
var record = localeStore.getById(this.valueOf()) ;
if(record === null) {
alert('Missing translation for: ' + this.valueOf()); // Key is not found in the corresponding messages_<locale>.properties file.
return this.valueOf(); // Return key name as placeholder
} else {
var value = record.get('value');
}
return value;
}
String.prototype.translate = translate;
callback.call(); // call back to caller(app.js / Ext.Application), loading rest of application
}
});
As an example from a view:
this.copyButton = Ext.create('Ext.button.Button', {
disabled: true,
text: 'DOCUMENT_LIBRARY_MENU_COPYTO_BUTTON'.translate(),
action: 'openCopyDialog'
});
Bundle on the server (mesages_en.properties):
DOCUMENT_LIBRARY_MENU_COPYTO_BUTTON=Copy file
etc..
Pros:
No-fuss code, 'Your_key'.translate() makes it easy to read and aware that this is a localized string
None/little maintenance overhead (Keeping an override file for each locale? Jesus..)
You only load the locale you need - not the whole shabang.
If you really want to, you could even have your own translation for the ExtJS locale files in the same bundle.
You could write unit tests to ensure that all bundles contain the same keys, thus avoiding orphaned translations later
Cons:
Synchronous - the store must be loaded before your main app starts. I solved this by adding a callback from the utility class which was called once all texts were loaded.
No real-time population of texts.. though I didn't want to make my users overload the server either :P
So far my approach has worked out pretty well for my requirements.
Site load isn't noticeably slower and the bundles (containing ~200 keys/values per bundle) measure out at ~10kb during load.
There is currently no solution so I decided to create my own hack/addon on the Ext.Loader. I uploaded the code on GitHub: https://github.com/TigrouMeow/extjs-locale-loader. It's exactly what I needed and I really hope it will help others as well!
You should first complete your development phase and build your project or use ext-all.js file to I18s translate your UI
see: http://docs.sencha.com/ext-js/4-0/#!/example/locale/multi-lang.html
The appropriate language modifier script (/ext/local/ext-lang-xxx.js) needs to be loaded after ext is loaded (including dynamically loaded classes). In the example above, I would have probably used Ext.Loader.loadScriptFile but they eval a downloaded one directly. The only other thing is that your classes need to be built in different languages or you just use variables and reference the lang-specific variable file.
you could also use a variable in the Loader paths:
var lang='fr';
Loader
{
paths:
{
'Ext': '.',
'My': './src/my_own_folder'+'/'+lang
}
It sounds like a dumb question and FAQ as well, but I truly don't see any reason not to be able to run it.
I try to run a imagerotator with SWFObject and that's the error I get. I do include properly the swfobject.js file (accessible via the direct url) and I pass the parameters through an XML file which loads independently fine as well. I do use version 2.2.
Here there is my SWF call:
<div id="slide1">Get the Flash Player to see this rotator.</div>
<div id="rotator"></div>
<script type="text/javascript">
var s1 = new SWFObject("/admin/cms/imagerotator.swf","rotator","606","199","5");
s1.addVariable("file","imagerotator.php");
s1.addParam("allowfullscreen","false");
s1.addVariable("linkfromdisplay", "false");
s1.addVariable("transition","lines");//bgfade,blocks,bubbles,circles,fade,flash,fluids,lines,random,slowfade
s1.addVariable("rotatetime","5");
s1.addVariable("overstretch","false");
s1.addVariable("backcolor","0xFFFFFF");// change if its helps to fit better in design (optional)
s1.addVariable("shuffle","false");
s1.addParam("wmode", "transparent");
s1.addVariable("showicons","false");
s1.addVariable("shownavigation","false");
s1.write("slide1");
</script>
I doubt that this usage of the SWFobject is completely inappropriate for this version, although I use a sample code of a CMS including this exact version of the library.
The implementation changed:
1) Your problem is described (and solved) here.
2) Check the original docs here.
Basically you need to use swfobject.embedSWF(...) now instead of var x = new swfobject(...)
In any case, Google is your friend on this one ;)