Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Sulla Faex
May 14, 2010

No man ever did me so much good, or enemy so much harm, but I repaid him with ENDLESS SHITPOSTING
Duck monster I've always considered you to be a sort of programmer's George R. R. Martin, and posts like this remind me why.

"Nothing good ever happens and every hope and dream you ever had will be torn screaming to the ground and fed into the churning maw of hell itself"

Adbot
ADBOT LOVES YOU

Sulla Faex
May 14, 2010

No man ever did me so much good, or enemy so much harm, but I repaid him with ENDLESS SHITPOSTING
I'm hearing a lot of good things about Knockout and their approach to documentation and the community seems pretty impressive, as well as the product itself being a no-fuss, common sense sort of affair.

I'm learning Laravel now and I'm finding that, apart from the woeful lack of proper documentation (I just recently found the API which looks to be a lot better a resource than their website), that also has quite a low learning curve without limiting or dumbing down the final product.

Is knockout the same? I'm not going to run into any weird glitches or hacked-together workarounds for pretty common use cases because of a weird design philosophy, or spend 4 months learning it and then find out that I'd have been better off spending 5 months and learning a more powerful framework?

I'm primarily looking for just a simple and elegant way to manage javascript elements and input that lets me focus on the more important non-front end logic. I don't need my javascript to do anything terribly fancy, it just needs to be clean and simple and extensible for when I add functionality/complexity later. So far everything I've seen points towards it being perfect at that, especially in terms of not having to go back and re-write everything each change or expansion.

Sulla Faex
May 14, 2010

No man ever did me so much good, or enemy so much harm, but I repaid him with ENDLESS SHITPOSTING
e: Update -- Looks like I resolved it, see the one-line update at the end if you want

Has anybody using knockout.js had an issue with observables not working properly? On certain page loads (if I don't wipe the browser cache) it will load the HTML before executing the javascript and all the data binds screw up. The foreach is screwed and what should be an empty observable array is shown as [object Object], etc. For example:

code:
<!-- ko if: AddedTagsArray().length > 0 -->
	Test if clause
	<!-- ko foreach: AddedTagsArray() -->
		<a href="" data-bind="click: function() { $parent.removeTag($data) }"><span data-bind="text: $data"></span></a> 
	<!-- /ko -->
<!-- /ko -->
After a hard refresh it works fine. But after subsequent refreshes it ignores everything and displays 'Test if clause [object Object]', and none of the other triggers work - they display things like $parent not defined, $root not defined, etc. Curiously enough the functions that don't take input variables or use observables work fine (for example a simple input wipe function that's called through a data-bind click: event).

I assumed this is the result of knockout being loaded too late, except my load order is: jquery (hosted on google's cdn), knockout (hosted locally) and then my site's js including the code that initialises knockout. I've tried loading them at the start of the page and at the end, and with the libraries at the top and my js code at the bottom.

I've tried shifting the asset load order around, moving things in and out of document ready, and I can't figure out any pattern to it. Even when I load the page in chrome incognito for the first time it has this issue. I checked the network log and they're getting status 304 (not modified -- signifies cached) but when I modify code it still has the same issue. I can't imagine the local browser is caching javascript variables between page loads but just to make sure I even set the self.AddedTagsArray to null and then .removeAll() before and after initialising the observable and it's still just throwing [object Object].

When you click on [object Object], which is a link as per the code above, this error gets returned:

code:
Uncaught ReferenceError: $parent is not defined 
So for some reason knockout is just not loading at all. Before it was just for subsequent refreshes after a hard load, but now it's basically every time and I can't get proper functionality again. (fake edit: Just waited a few minutes and tried a hard refresh; working perfectly on this load, second load hosed up). I've tried this on my girlfriend's computer and that's actually where I first noticed the errant behaviour.

Does anybody have any idea what this could be? There's nothing in the PHP error logs for the server (Debian running nginx/php, website is running laravel/jquery/knockout).

I'm just scratching my head super hard because there are no errors in the browser or unloaded resources etc. It's not being cached because when I modify the source code I can see it being re-downloaded by the server.

e: I'm doing some more tests now and for some reason when I add the knockout code to within document ready, document ready doesn't get executed -- I'm doing test variables outside and inside that block and the ones inside it aren't getting made. But when I remove it from the document ready block sometimes it works again, sometimes it doesn't, but when it doesn't work the other (non-KO) variables still get made. I'm still so confused...

Here's the whole KO js just in case I'm doing something hopelessly stupid:

code:
    var viewModel = function() {
        var self = this;
        self.AddedTagsArray = null;
        self.AddedTagsArray = ko.observableArray();
        self.AddedTagsArray.removeAll();
        self.addTagInput = ko.observable('');
        
        self.addTag = function(newtag) {
            if (newtag == "" || newtag == undefined) {
                return false;
            }
            if (self.AddedTagsArray.indexOf(newtag) < 0) {
                self.AddedTagsArray.push(newtag);
            }
        }
    
        self.addTagInput_wipe = function() {
            self.addTagInput('');
        }
    
        self.removeTag = function(tag) {
            if (!(self.AddedTagsArray.indexOf(tag) < 0)) {
                self.AddedTagsArray.remove(tag);
            } 
        }
    
        self.setFocus = function(element) {
            $(element).focus();
        }
    }

    ko.bindingHandlers.returnKey = {
        init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
            ko.utils.registerEventHandler(element, 'keydown', function(evt) {
                if (evt.keyCode === 13) {
                    evt.preventDefault();
                    evt.target.blur();
                    valueAccessor().call(viewModel);
                }
            });
        }
    };
    ko.applyBindings(new viewModel());
And a copy-paste of the actual page that calls/interacts with the data:

code:
<input type='text' id='addtag' data-bind="value: addTagInput, returnKey: function() { addTag($root.addTagInput()); addTagInput_wipe(); $root.setFocus($element) }">
                                <input type='button' id='addtag_submit' value='Go' data-bind="click: function() { addTag($root.addTagInput()); addTagInput_wipe() }">

<!-- snip -->

<!-- ko if: AddedTagsArray().length > 0 -->
                                    <!-- ko foreach: AddedTagsArray() -->
                                    <a href="" data-bind="click: function() { $parent.removeTag($data) }"><span data-bind="text: $data"></span></a> 
                                    <!-- /ko -->
                                <!-- /ko -->

<!-- snip -->

<button class="tag" data-bind='click: function() { addTag(<?php echo $tag; ?>) }'>
                                    {{ $tag }}
                                </button>
And.. that's it.

e: Update -- Okay so a google search pointed me to requirejs and after 10-15 minutes of figuring that out and ensuring that my code wouldn't be executed until knockout was loaded, it's all working. Hooray!

Sulla Faex fucked around with this message at 09:26 on Apr 10, 2014

Sulla Faex
May 14, 2010

No man ever did me so much good, or enemy so much harm, but I repaid him with ENDLESS SHITPOSTING
edit: Disregard this post, I just installed a knockout-specific debugging tool to chrome and it looks like knockout observables are actually working after all, it's just that everything I'm using them for is failing for some reason without a hard refresh. It could be that the page loads too quickly from cache and my code is loving up somehow as a result. I'll look into it.

Okay so that Knockout problem I described earlier in the page never really went away, but it has stabilised -- on a hard reload (i.e. ctrl + f5) it loads everything fine. Every subsequent reload fails to process the knockout bindings - no observables, stuff that should be hidden by knockout isn't, etc.

I've spent an hour or two looking into it and I've actually forced all javascript files (jquery, knockout, require.js, and my own custom scripts) to download afresh from the server using a cache-busting rewrite in nginx. Each js file is called using a _cache23587345.js where the numbers are randomised each time.

code:
ewrite ^(.*[\\\/])(.+(?=_cache))_cache\d+\.js$ $1$2.js;
And it's STILL loving up. Even on first load in chrome incognito. In firefox base load doesn't work, even the very first access - you need a HARD refresh for it to load everything.

Anybody experienced anything like this?? I can't think of what's going on. Chrome dev tools don't show any problems with loading scripts etc, and there's no discernible difference between the load order etc in a normal (broken) load and the load after a hard refresh.

Sulla Faex fucked around with this message at 12:13 on Apr 13, 2014

Sulla Faex
May 14, 2010

No man ever did me so much good, or enemy so much harm, but I repaid him with ENDLESS SHITPOSTING
Does anybody have a good 'best practices' guide for npm security? i want to check out angular but i also remember the flatmap (flatstream?) fiasco a few months ago and i must suck at googling because i cant find a good, plain retrospective on how to offset npm's inherent security risks

Sulla Faex
May 14, 2010

No man ever did me so much good, or enemy so much harm, but I repaid him with ENDLESS SHITPOSTING
e: hang on i'm pretty tired so i'm going to keep working on it, possibly sleep and try again in the morning, because i'm getting all turned around

e2: oh man i just lost a solid hour and a half because i didnt realise that the Vuex store you create and reference still has to be called store. like, you can't arbitrarily call it whatever you want that makes sense within your app, it has to be store, and it wasn't just a naming convention for the examples. oh man i'm so sloppy, haha

Sulla Faex fucked around with this message at 00:42 on Feb 7, 2019

Adbot
ADBOT LOVES YOU

Sulla Faex
May 14, 2010

No man ever did me so much good, or enemy so much harm, but I repaid him with ENDLESS SHITPOSTING
You could style every temporary or non-finalalised element with the same orange templating skin they use in valve video game level design. Remind them before each demo that it's temporary, then any time some stakeholder comments on it just say "I see". No commitment, no promise, just an explicit acceptance that some noise came out of their mouth and it would be rude not to acknowledge that they succeeded in makig noise with their mouth

Then immediately pipe to /dev/null and move on with your life. If they later ask why you didn't change it, and they will, and if you can find a way to still be OK with that and not quit to get away from these people, let me know your secret, because goddamn

I might still be bitter because my last two projects had stakeholders so dumb that if you melted them down for school glue you'd nuke the next 4 generations of students

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply