I can't seem to initialize my view. I tried looking around to see if this was asked before, but none of the solutions were working for me. My backbonejs view is below:
class FRView extends Backbone.View
el: $ 'fr_view'
initialize: ->
console.log("created")
render: ->
console.log("here")
I'm attemtpting to intialize it inside of a partial using the code below:
:javascript
var curr_view = new FRView()
but I keep getting the following error:
Uncaught ReferenceError: FRView is not defined
I've also tried
:javascript
var curr_view = new Backbone.View.FRView()
Which lead to the following error:
Uncaught TypeError: Backbone.View.FRView is not a constructor
From chrome sources browser I can see that the FRView file is loaded. I've also tried wrapping it in document onload but that didn't help. Any idea what might be causing this issue?
I see two bugs, one you know about and one that you'll find out about soon.
The first problem (the one you know about) is caused by CoffeeScript's scoping system:
Lexical Scoping and Variable Safety
[...]
Although suppressed within this documentation for clarity, all CoffeeScript output is wrapped in an anonymous function: (function(){ ... })();
So your FRView ends up looking more or less like this in JavaScript:
(function() {
var FRView = ...
})();
and that means that FRView is only visible inside your CoffeeScript file.
The easiest solution is to put the class in the global scope:
class #FRView extends Backbone.View
or equivalently:
class window.FRView extends Backbone.View
Another common solution is to define a global namespace for your app and then put your class in that namespace:
class YourNameSpace.FRView extends Backbone.View
and say new YourNameSpace.FRView when instantiating it.
The other problem is that your el looks a bit confused:
el: $ 'fr_view'
There are two problems here:
That will be looking for an <fr_view> element in your HTML and you probably don't have such a thing. I'd guess that you really have something like <div id="fr_view"> or maybe <div class="fr_view">, in that case you'd want to say:
el: '#fr_view' # If you're using an id attribute.
el: '.fr_view' # If you're using a CSS class.
$ 'fr_view' will be executed when the JavaScript is loaded and the element might not exist at that time. The solution to this problem is to use just the select for el as above. There's no need to use a jQuery object for el, Backbone will do that for you when the view is instantiated.
As 'mu is too short' pointed out, the issue rooted from namespace/declaration issues. After googling around about namespace I skimmed through this and fixed the issue by changing my backbonejs view to:
class Portal.Views.FRView extends Backbone.View
el: $ '#FRView'
initialize: ->
console.log("created")
render: ->
console.log("here")
and instantiated it using:
:javascript
var frview = new Portal.Views.FRView();
Related
I have a dart function:
_addSelection(HtmlElement ele){
ele.classes.add("selection");
}
I would either want 1 or 2 things to occur, either A) execute an on-tap and on-track function given the selection class.... OR Dynamically add the on-tap and on-track attributes referencing reflected dart functions.
I have 2 functions:
#reflectable
onTap(CustomEventWrapper cew, params){
//...
}
#reflectable
onTrack(CustomEventWrapper cew, params){
//...
}
I was looking at the HtmlElement class and documentation and I wasnt quite understanding how to do this.
Edit if I were using jQuery and Javascript, I would be doing something as simple as:
$(document).on("tap", function(){});
$(document).on("track", function(){});
Edit2 Added Angular Dart because both designs leverage Dart backend and markup front end.
You could do:
_addSelection(HtmlElement ele) {
ele.classes.add("selection");
ele.onTouchEnd.listen((TouchEvent touch) {
...
});
}
That would give you something close to the tap event. If you wanted to get really fancy you could also listen for onTouchStart and only call your onTap handler when the time between the start and end is small.
I'm trying to work through a Google I/O codelab for the Material Design Web App, but port it to the Dart language. http://io2014codelabs.appspot.com/static/codelabs/polymer-build-mobile/#4
I'm at the step where you toggle the drawer, but I can't figure out the dart equivalent.
The JS code to toggle the drawer looks like this:
<script>
Polymer('codelab-app', {
toggleDrawer: function() {
this.$.drawerPanel.togglePanel();
}
});
</script>
I have tried the following in my CodelabApp class, but I get a NoSuchMethodError: method not found: 'togglePanel'
#CustomTag('codelab-app')
class CodelabApp extends PolymerElement {
CodelabApp.created() : super.created() {}
void toggleDrawer() {
querySelector('core-drawer-panel')..togglePanel();
}
}
my button element properly fires, but I can't figure out how to call the drawer's togglePanel method. <paper-icon-button icon="menu" on-click="{{toggleDrawer}}"></paper-icon-button>
any help or direction to the proper docs would be greatly appreciated.
UPDATE:
This has been fixed in recent versions: https://github.com/dart-lang/core-elements/issues/39
Updating the polymer and core_elements libraries works as expected.
While attempting to commit my own fix to this, I discovered a temporary workaround that works in my case. Maybe will work for you :)
Add the following to the top of your file:
import 'dart:js' show JsObject;
_js(x) => new JsObject.fromBrowserObject(x);
Then change your custom tag code:
#CustomTag('codelab-app')
class CodelabApp extends PolymerElement {
CodelabApp.created() : super.created() {}
void toggleDrawer() {
_js(shadowRoot.querySelector('core-drawer-panel')).callMethod('togglePanel');
}
}
For reference I found this solution by reading through the code here:
https://github.com/dart-lang/core-elements/blob/master/example/core_drawer_panel.html#L68-L81
I'm currently calling a jQuery based plugin called Bootstrap Context Menu.
In order to call it, I need to use the Javascript Interop library. But when I call a jQuery method from it I receive the following warning:
The method 'jQuery' is not defined for the class 'Proxy'
Code snippet:
js.scoped(() {
js.context.jQuery('#canvas').contextmenu();
});
This was not happening before some dart/js-interop updates. What is the right way to get rid of this warning?
You get this warning because the new analyzer doesn't seem to be aware of the option Report 'no such member' warnings when class defines noSuchMethod() ( Reported at http://dartbug.com/10016 ). If you switch back to the legacy analyzer you shouldn't see this warning anymore.
That said if you want to use the new analyzer and get rid of this warning you can use the array notation like this :
js.context["jQuery"]('#canvas')["contextmenu"]();
But :
it's less readable particullary for method calls.
it's less efficient for method calls because 2 operations are done ( f = js.context["jQuery"] followed by f('#canvas') ) instead of 1 ( js.context.jQuery('#canvas') )
I've recently started using coffeescript in my rails projects pretty heavily.
I'm curious how you make a free standing function. So if I do:
foo = ->
alert("hello world")
That compiles to
(function() {
var foo;
foo = function() {
return alert("hello world");
};
}).call(this);
How do I make it compile to
var foo;
foo = function(){
return alert("hello world");
}
I want to be able to call use link_to_function "foo"
There are actually several ways you can accomplish this (one way already given in the comments).
Compile without the closure wrapper
This will expose all functions to the outer scope. This may be an option if you are using a lighterweight framework where you can control of the build process. I'm not sure you would be able to within the context of the asset pipeline but works great in the context of a small sinatra app.
coffee -b myfile.coffee
Attach to a global object
If you know you are targeting a specific runtime, like the browser you can use the global window object.
window.foo = -> alert("hello world")
This is the same effect as the solution in the comments since the target is a Rails environment. But using # which is sugar for this. will attach it to whatever the scope of this is at the moment. Assuming the function is not being defined in a callback or an internal object with a bound context, it would likely be the window object.
#foo = -> alert("hello world")
Better would be to create your own namespace and attach that way:
Mine ||= {}
Mine.foo = -> alert("hello world")
#Mine = Mine
CoffeeScript classes
Or use CoffeeScript's class syntax to do the same by attaching to the prototype itself:
class #Mine
#foo: -> alert("hello world") # called as Mine.foo() (notice the # declaration)
In our rails applications we typically have an asset that defines the namespace, aka a file at app/assets/javascripts titled mine.coffee:
window.Mine ||= {}
and then in other files we can require that namespace:
#= require mine
class Mine.MyOtherThing
#foo: -> alert("hello world")
I have recently started using coffeescript with Rails and I am finding that sometimes the generated javascript does not get the function safety wrapper.
Here is a sample project demonstrating it.
For example, this CS code, in index.js.coffee:
class Foo
afunc: ->
alert("afunc")
Correctly becomes:
(function() {
var Foo;
Foo = (function() {
function Foo() {}
Foo.prototype.afunc = function() {
return alert("afunc");
};
return Foo;
})();
}).call(this);
But this code, from other.js.coffee:
class App.Func
ouch: ->
alert("ouch")
becomes this un-wrapped version
App.Func = (function() {
function Func() {}
Func.prototype.ouch = function() {
return alert("ouch");
};
return Func;
})();
It seems to be due to the "App." prefix - which I can see affects naming/scope - but why is coffeescript compiling it differently...
App is defined in setup.js.coffee, like this:
window.App =
Models: {}
Which also does not get wrapped, unless I add a class into that file too.
I am sure it must be my misunderstanding - so thanks in advance for the pointers to the manual :).
EDIT:
I created this question as I thought it might be behind some issues I was having with my backbone/coffeescript app, but it seems that it was not. As the class is linked to a public/global thing "App", it seems to work wrapped or not. Still would be useful to know why its happening - is it by design?
The "function safety wrapper" feature you are using works to prevent local variables from being set on the global namespace. Since setting an object property (App.Func) doesn't affect the global namespace, the declaration is not wrapped in a function.