ember.js add child views - view

I have the following code snippet:
App.TripLegView = Em.View.extend({
transportMeanType: null,
transportMeanTypeChanged: function () {
this.carView = App.CarView.create();
var childView = this.createChildView(this.carView );
this.get('childViews').pushObject(childView);
}
}).observes('transportMeanType'),
App.CarView = Em.View.extend();
However when i debug the above code, the child view does not seem to be added to the childViews array.
Can anyone explain how to correctly add child views.

First of all, it seems you are misusing the observes(), it should be defined on the function.
If you want to manipulate childviews, I think you should use Ember.ContainerView
Your code would be like this:
App.CarView = Em.View.extend();
App.TripLegView = Em.ContainerView.extend({
transportMeanType: null,
transportMeanTypeChanged: function () {
this.carView = App.CarView.create();
var childView = this.createChildView(this.carView );
this.get('childViews').pushObject(childView);
}.observes('transportMeanType')
});
If it doesn't work, please post a jsfiddle to give an example.

Related

casperjs evaluate function returns invalid value

I'm now using casperjs for web crawling. Almost everything is good, but I faced some trouble. First, my code is like below.
casper.start().each(SOME_URLS, function(self, URL) {
self.thenOpen(URL, function() {
self.then(function() {
var getDatas = function() {
var title = $('SOME_SELECTOR').map(function() {
return $(this).text();
}).get();
return {
title: title
};
}
data = self.evaluate(getDatas);
console.log(JSON.stringify(data));
});
});
}).run();
I want to get some data from webpage to 'data' variable. Sometimes data is perfectly good(on console.log), but sometimes, data is empty!
Why this happening? What did I wrong?
The problem is you cant call casper.start more than once. Your loop needs to inside the casper.start function or inside a casper.then
See this excellent SO answer to help you do this.
Basically only call casper.start once and place your loop inside a casper.then

Jasmine spy doesn't work on a function defined in a constructor

I want to spy on a function used as a click handler. The function is defined within the constructor of a closure.
var viewModel = function(){
var viewModel = function(){
var _this = this;
_this.internalClickHandler = function(){
console.log('I handled a click');
}
}
return viewModel;
}();
var testViewModel = new viewModel();
var theSpy = spyOn(testViewModel, 'internalClickHandler');
Even though Jasmine is happy that 'internalClickHandler' exists and creates the spy, it never gets called. In fact the original function (internalClickHandler) gets call instead.
I've created examples in codepen.io that show the problem. The failing test is the one trying to spy on a function in the constructor.
My event handler needs to be in the constructor as it needs access to instance of the object and I do want to test that the correct handler has been fired not just that the click event was triggered.
Any help would be greatly received. Thanks
You will not be able to execute that test because of the following reasons:
Your clickHandler actually gets reassigned to a different variable
on the DOM Element onClick, see this line
document.getElementById('testLink').addEventListener('click',
_this.internalClickHandler);
When a click trigger gets invoked, it actually executes the function
onClick and NOT internalClickHandler, though they are in actuality(code wise)
the same but they are being referenced by two different variables
i.e onClick & internalClickHandler.
You are better off trying something like this.
it('should spy on a event binding defined in constructor', function() {
var testViewModel = new viewModel();
var tl = document.getElementById('testLink');
var theSpy = spyOn(t1, 'onclick');
//$('#testLink').trigger('click');
var event = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true
});
tl.dispatchEvent(event);
expect(theSpy).toHaveBeenCalled();
tearDown();
});
Hope this helps.
I resolved this by using as the handler an anonymous function wrapping a reference to internalClickHandler. This way the original function still gets called and I'm able to spy on it.
var viewModel = function(){
var viewModel = function(){
var _this = this;
_this.internalClickHandler = function(){
console.log('I handled a click');
}
}
return viewModel;
}();
var theViewModel = new viewModel();
var theSpy = spyOn(testViewModel, 'internalClickHandler');
$('#testLink').on('click',
function(){
theViewModel.internalClickHandler(); //<-- The anonymous function calls internalClickHandler
});

jquery replaceWith() not working in $.post function [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 8 years ago.
I'm trying to make a to-do list type thing.
Here, I want the new goal to be saved to the database, and then for only the div with the relevant list to refresh, showing the list with the new goal added.
The database updates fine, the new html with the new list item is returned just fine, but
.replaceWith() doesn't seem to work. Nothing happens.
It works outside of that function, but not inside of it, and I'm not sure why.
$('.addGoal').submit(function(event){
var listid = $(this).attr('id');
var desc = $(this).children('.goalinput').val();
event.preventDefault();
if(desc == "") {
console.log("empty!");
return;
}
var posting = $.post("updatedata.php", { what :'addgoal', id: listid, data: desc});
posting.done(function(data){
console.log("saved!" + data); //this works, the updated html is being returned
$(this).closest('#goallist').replaceWith("Returned data goes here"); //this works outside of this function but not inside of it.
});
});
this doesn't automatically keep its value in the callback function. You need to bind a closure variable:
$('.addGoal').submit(function(event){
var listid = $(this).attr('id');
var desc = $(this).children('.goalinput').val();
event.preventDefault();
if(desc == "") {
console.log("empty!");
return;
}
var that = this; // Closure variable
var posting = $.post("updatedata.php", { what :'addgoal', id: listid, data: desc});
posting.done(function(data){
console.log("saved!" + data);
$(that).closest('#goallist').replaceWith("Returned data goes here");
});
});
Please see
How to access the correct this / context inside a callback? for an explanation and solution for the general problem, and
$(this) inside of AJAX success not working for a similar problem with $.ajax
But since IDs are supposed to be unique in an HTML document anyway, you can replace $(this).closest('#goallist') with $('#goallist') and completely ignore this.

Put List into jQuery script MVC3

I use jQuery UI Autocomplete.
Part of script is:
$("input[data-autocomplete]").each(function () {
var availableTags = ["first", "second"];
And it works -autocomplete with "first" and "second"
Now i want to assign avalibleTags dinamicly like something like:
var availableTags = #Viewbag.Something
or
var availableTags = #Url.Action('Tags","Home")
It is possible? How to do it in a good way?
In your view you can do:
<script type="text/javascript">
$(function () {
var MyTags = $.getJSON('#Url.Action("Tags","Home")' function (MyList) {
// Do something with List
// var avaliableTags = MyList;
});
});
</script>
(This uses JQuery)
Would work. Where the action is in controller like:
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult Tags()
{
var MyList == YOUR TAGS
return Json(MyList , JsonRequestBehavior.AllowGet);
}
Note, the use of the attribute and JSON to allow Javascript communication.
Edit: woops, used key words.
Sure, just make sure to JSON encode it:
var availableTags = #Json.Encode(ViewBag.Something);
and since I hate ViewBag and recommend you always using view models and strongly typed views:
var availableTags = #Json.Encode(Model.Something);
This assumes that Something is an array of strings property on your view model so that when the page is rendered you will get:
var availableTags = ["first", "second"];
and will be able to use it with the autocomplete plugin.

Methods for a specific object (not prototyped)

I'd like to write a plugin that can be used in the following manner:
var img = $('#someImage').Image();
or perhaps:
var img = $.Image({id: 'someImage', src: '/...'});
and then be able to do image-related functions:
img.highlight();
img.showAlter();
et cetera. However, I don't want to do:
$.fn.highlight = function() {}
since that would apply to all jQuery objects and i want my method to apply only to those objects I've called .Image() on.
is what I'm asking for possible? how?
You'd need to place your Image function on the prototype (fn), but then have the Image plugin assign the highlight and showAfter functions to that specific jQuery object on which .Image() is called.
(function( $ ) {
$.fn.Image = function( props ) {
this.highlight = function(){
this.each(function() {
$(this).css('border', "5px dashed yellow");
});
};
this.showAfter = function(){};
return this;
};
})( jQuery );
var img = $('img').Image();
img.highlight();
EDIT:
To clarify, this in the Image function is a reference to the jQuery object against which Image() was invoked.
this does not reference the Image function in any way.
Example: http://jsfiddle.net/saYLm/
$.fn.image.highlight = function() {}
assuming you have written a plugin named image this would prototype the highlight function to that object

Resources