Apparently, there is a part2 in my struggle with this ‘current user hyperlink’ that I inserted in my LightSwitch HTML client as a custom ‘control’…
At first sight, the link works perfectly: when you click it, the app shows a popup where you can edit your profile. Because of the databinding, the hyperlink will automatically update its text when the user edits his/her name in that dialog.
At first sight…
Once I added multiple screens to my application, I noticed that the hyperlink databinding behaves correctly when I first open the screen, but after navigating to another screen and then back again, my custom control stopped working. In fact, after navigating to another screen and then back again, half of my custom controls were behaving funny, the other half was just fine. And by the time I noticed this subtlety, I had way too much custom controls on my screen to log it as a ‘known issue’ 😉
I don’t remember ever running into problems with this before, but apparently there is a subtle difference in behavior between two different ways I interact with my custom ‘controls’. Zooming in on the ‘offending’ code reveals the problem (when you know where to look, bugs are always easier to find):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var userViewer = $('<a id="userviewer" href="#" target="_self" >' + user.Name + '</a>'); | |
userViewer.appendTo($(".msls-screen-buttons")); | |
//interaction 1 | |
userViewer.on('click', function () { | |
myapp.showEditMyProfile(user); | |
}); | |
contentItem.dataBind("value.Name", function () { | |
//interaction 2 | |
$("#userviewer").text(contentItem.value.Name); | |
}); |
I create the usercontrol via a JQuery selector, then save a ‘reference to the usercontrol’ in a variable. In my first interaction, I use this variable directly. For some reason, in my second interaction, I use a new JQuery selector to get a new ‘reference to the same usercontrol’.
This seems to work fine for the very first time, but breaks silently on subsequent rendering.
The first fix seems to be the obvious: use the variable instead of using a new JQuery selector.
A second fix that seems to work, is to start the JQuery selector using the parent element (passed as an argument to your _render or _postRender functions) as the context:
$("#userviewer", element);
If anyone can enlighten me as the technical reasoning behind this issue, I’d love to hear it 🙂 Until I understand, I think I’ll stick with this last approach because it seems to be the most stable one…
Keep rocking LS!
Jan
Pingback: Why your hyperlink won’t work the LS HTML client | Jan Van der Haegen's blog
Hey Jan, you sure are doing beautiful things with LightSwitch!
Thanks man, that means a lot to me!
Keep rocking LS!
With javascript, due to my lack of better understanding, I always chalk it up to a ‘timing thing’. Curious though does this work:
contentItem.dataBind(“value.Name”, function (newValue) {
//interaction 2
$(“#userviewer”).text(newValue);
});
Hey Josh!
Just tried and pretty much the same effect. It’s not really the binding, but this: $(“#userviewer”)
The first page ‘render’, this works just fine. The second time, this seems to be unable to actually get the correct reference…
JavaScript… Still not sure if I love it or hate it…
Anyways, what are you doing here on my blog? Should you not be working on getting the community more declarative data-binding examples to avoid this mess in the first place? 😀 😉
Keep rocking LS!!!
Jan
Ha, I always read your blog, Jan and since you mentioned recent examples, I’ll plug something cool I found today the ContentControl:
http://joshuabooker.com/Blog/Post/13/msls-Exposed–Declarative-Binding
Marvellous!!!
Keep rocking LS, you’re doing great!!
Jan
Hello Jan. I’m having the same issue. Everything renders fine on the first visit. Did you find out what was causing this behavior?
Nope, still guessing as to the cause. At least we have a workaround 🙂
Pingback: LightSwitch Community and Content Rollup – May 2014 - Visual Studio LightSwitch Team Blog - Site Home - MSDN Blogs
Hi Jan, first of all, congratulations and good luck with App-stitch!
Now, a cry for help:
I ran into a similar issue (like many others), with a screen with no visual collection, and all custom controls that render JavaScript-based charts. The first time the screen is loaded, everything works perfectly fine. Navigating away and then coming back, no chart is rendered.
My only JavaScript experience comes from learning LightSwitch. I don’t know if/how your workaround would fix my problem. Can you give me a hint? Basically, the “offending code” looks like this:
myapp.myScreen.myCustomControl_render = function (element, contentItem) {
//Create chart container
$(element).append(”);
contentItem.dataBind(“screen.YearFilter”, function (newValue) {
if (newValue && newValue != -1) {
contentItem.value = newValue;
}
else if (newValue == -1) {
contentItem.value = newValue;
}
else {
contentItem.value = -1;
}
//Draw chart
$(document).ready(function () {
$.getJSON(“../api/myController/” + contentItem.value, function (data) {
options.series[0].data = data;
options.title.text = titleText;
var chart = new Highcharts.Chart(options);
});
});
});
};
big hug!
I forgot WordPress strips the HTML code, inside the .append there was a div element with an id.
Nevermind, I managed to try your workaround and it fixed the issue. Thanks!
Hey Nicolas!
Sorry I was out for a quick vacation. Glad you already sorted that out.
Keep rocking LS!!
Jan
Hi Jan, recently I have contacted Syncfusion Support for a similar issue with a JS Chart, and sent them a sample app. After a few days they’ve found that the chart container is created every time the navigation button is clicked. When navigating from the page with chart to start page the contents of chart screen will be hidden so clicking chart navigation button again will create a new container with same id as previous one. Now the page will have two chart containers one with chart (hidden) and an empty container. Chart will be drawn to the hidden container because it was added first. As a workaround solution, you can remové the existing container before adding a new one, using JQuery:
//Remove existing Chart container from page
var ChartContainer = document.getElementById(“Chart2”);
if (ChartContainer)
$(“div#Chart2”).remove();
Hope this helps.
Wow,
thank you so much man!! You rock!
Keep rocking LS
Jan