Migrating from YUI2 to YUI3 and domready - yui3

I want to migrate the javascript in my site from YU2 to YUI3, but I am only a poor amateur programer and I am stuck at the first pitfall.
I have the following code:
MyApp.Core = function() {
return {
init: function(e, MyAppConfig) {
if (MyAppConfig.tabpanels) {
MyApp.Core.prepareTabpanels(MyAppConfig.tabpanels);
}
},
prepareTabpanels: function(tabpanels) {
// Code here
}
}
}();
var MyAppConfig = {
"tabpanels":{"ids":["navigation"]}
};
YAHOO.util.Event.addListener(window, "load", MyApp.Core.init, MyAppConfig);
How can I pass the MyAppConfig object to the MyApp.Core.init function by using YUI3 "domready" event listener?
Thanks in advance!

You should be able to do something like:
var MyApp = {};
MyApp.Core = function(){ return {
init: function(MyAppConfig) {
console.log(MyAppConfig);
},
prepareTabpanels: function(tabpanels) {
// Code here
}
}
}();
var MyAppConfig = {
"tabpanels":{"ids":["navigation"]}
};
YUI().use('node', 'event', function(Y){
Y.on('domready', MyApp.Core.init, this, MyAppConfig);
});
Note that the event is not passed in as the first parameter, it is the config.
Y.on accepts parameters as <event_type>, <callback_function>, <context>, <params>..
any parameter after the third item is passed through to the callback function so MyAppConfig becomes the first parameter in your init.
EDIT
See the YUI3 API documentation here: http://developer.yahoo.com/yui/3/api/YUI.html#method_on

Related

Vue is returning vm as undefined whenever I try to access it

I have the following bit of code:
Which prints the following in the console:
I've been bashing my head for a very long time, not sure where to go from here. It was working just fine when I pushed last. Then, I made some changes which broke it as you can see. To try to fix it, I stashed my changes, but I'm still getting this error.
Edit
search: throttle(live => {
let vm = this;
console.log("entered!!!");
console.log("this", this);
console.log("vm", vm);
if (typeof live == "undefined") {
live = true;
}
if (!live) {
// We are on the search page, we need to update the results
if (vm.$route.name != "search") {
vm.$router.push({ name: "search" });
}
}
vm.$store.dispatch("search/get", {
type: vm.searchType,
query: vm.searchQuery
});
}, 500)
Assuming search is in your methods it should not be using an arrow function as that will give you the wrong this binding.
Instead use:
methods: {
search: throttle(function (live) {
// ...
}, 500)
}
Here I'm also assuming that throttle will preserve the this value, which would be typical for implementations of throttling.
Like I said in my comment, I suspect this is a scoping issue.
Perhaps if you return the throttle function with the Vue component passed in, you might see better results:
search: function() {
let vm = this;
return throttle(live => {
console.log("entered!!!");
console.log("this", this);
console.log("vm", vm);
if (typeof live == "undefined") {
live = true;
}
if (!live) {
// We are on the search page, we need to update the results
if (vm.$route.name != "search") {
vm.$router.push({ name: "search" });
}
}
vm.$store.dispatch("search/get", {
type: vm.searchType,
query: vm.searchQuery
});
}, 500)
}

How call event in correct way in Module Pattern edition

After reading an article https://css-tricks.com/how-do-you-structure-javascript-the-module-pattern-edition/ I did something similar in my project - created the structure:
var SomeStructure = {
var1: $('#tag1'),
init: function() {
this.var1.on('click', function (e) {
SomeStructure.mouseClick(e);
});
},
mouseClick: function(e) {
e.preventDefault();
alert("tag clicked");
}
}
SomeStructure.init();
div {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="tag1">Click me!</div>
My code is working, but I wondering if it's possible rewrite the code:
this.var1.on('click', function (e) {
SomeStructure.mouseClick(e);
});
so that the call of function mouseClick after clicking the $('#tag1') in some more neat way without anonymous function in one row, something like that:
this.var1.on('click', this.mouseClick);
But this way isn't right without e..
Thank you in advance.
I have to add a new function ListenEvents for events listening, so that a lot of new listeners could be added inside to make clear workflow object (as described here http://derickbailey.com/2015/08/07/making-workflow-explicit-in-javascript/) :
`var SomeStructure = {
var1: $('#tag1'),
init: function() {
this.ListenEvents();
},
ListenEvents: function() {
self = SomeStructure;
self.var1.on('click', self.mouseClick);
},
mouseClick: function() {
alert("tag clicked");
}
}
SomeStructure.init();`

Get data change with observer mutation?

I'm trying to get the changed value of a HTML-Node.
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if(mutation.addedNodes[0].data == "9"){
dostuff();
}
}
}
But javascript returns only an object and no array of
addedNodes.mutation.addedNodes[0]
prints out:
<TextNode textContent="9">
Where can I get the value of the changed HTML-Node?
Thanks alot.
Ok, found a solution via Stackoverflow
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
[].call(mutation.addedNodes).forEach(function (addedNode) {
if(addedNode.textContent == "9"){
dostuff();
}
});
});
});

ExtJS Callback Functions Example

I'm a newbie at ExtJs and I'm struggling to figure out how to use callback functions in ExtJs. The ExtJs version I'm using is 4.2.1
Basically I want to chain the execution of 2 functions:
func1: function() {
}
func2: function() {
}
so that func2() only starts executing after func1() completes.
From what I've read so far, I need to use callback function, but for the life of me I cannot get it.
Here Is my code:
filter: function (filters, value) {
if (Ext.isString(filters)) {
filters = {
property: filters,
value: value
};
}
var me = this,
decoded = me.decodeFilters(filters),
i = 0,
length = decoded.length;
for (; i < length; i++) {
me.filters.replace(decoded[i]);
}
Ext.Array.each(me.filters.items, function (filter) {
Ext.Object.each(me.tree.nodeHash, function (key, node) {
if (filter.filterFn) {
if (!filter.filterFn(node)) node.remove();
} else {
if (node.data[filter.property] != filter.value) node.remove();
}
});
});
me.hasFilter = true;
console.log(me);
},
clearFilter: function() {
var me = this;
me.filters.clear();
me.hasFilter = false;
me.load();
},
isFiltered: function() {
return this.hasFilter;
},
filterNavAdminSTByUserName: function (nameValue) {
this.clearFilter();
this.filter([{
property: 'userName',
value: nameValue
}]);
}
My problem is that this.filter() gets executed before this.clearFilter(); How do I force this.filter() to execute only after this.clearFilter() completes?
Thanks in advance!
After some soul searching I've finally figured out how callback functions work.
So here is the solution:
clearAndFilter: function (nameValue) {
var me = this;
me.filters.clear();
me.hasFilter = false;
me.load({
scope: me,
callback: function () {
// filter the store
me.filter('userName', nameValue);
}
});
},
filterNavAdminSTByUserName: function (nameValue) {
this.clearAndFilter(nameValue);
}
Feels good to answer to my first ever post here!

Durandal Custom View Location Strategy

I am trying to figure out how to use a custom view location strategy, I have read the documentation at this page http://durandaljs.com/documentation/Using-Composition/ but I don't exactly understand what the strategy function should look like.
Can anybody give me a quick example of what the implementation of this function would be like and the promise that returns (even a simple one) etc?
Thanks in advance,
Gary
p.s. This is the code in my html:
<div>
<div data-bind="compose: {model: 'viewmodels/childRouter/first/simpleModel', strategy:
'viewmodels/childRouter/first/myCustomViewStrategy'}"></div> </div>
and this is the code in my myCustomViewStrategy:
define(function () {
var myCustomViewStrategy = function () {
var deferred = $.Deferred();
deferred.done(function () { console.log('done'); return 'simpleModelView'; });
deferred.fail(function () { console.log('error'); });
setTimeout(function () { deferred.resolve('done'); }, 5000);
return deferred.promise();
};
return myCustomViewStrategy;
});
but I get the error:
Uncaught TypeError: Cannot read property 'display' of undefined - this is after done has been logged in the console window.
Okay I solved this by creating my custom view strategy by the following:
define(['durandal/system', 'durandal/viewEngine'], function (system, viewEngine) {
var myCustomViewStrategy = function () {
return viewEngine.createView('views/childRouter/first/sModelView');
}
return myCustomViewStrategy;
});
As I found the documentation a bit lacking on compose binding's strategy setting I checked the source code how it works. To summ it up:
The module specified by the compose binding's strategy setting by its moduleId
must return a function named 'strategy'
which returns a promise which results in the view to be bound
as a HTML element object.
As a parameter the strategy method receives the compose binding's settings object
with the model object already resolved.
A working example:
define(['durandal/system', 'durandal/viewEngine'], function (system, viewEngine) {
var strategy = function(settings){
var viewid = null;
if(settings.model){
// replaces model's module id's last segment ('/viewmodel') with '/view'
viewid = settings.model.__moduleId__.replace(/\/[^\/]*$/, '/view');
}
return viewEngine.createView(viewid);
};
return strategy;
});
Durandal's source:
// composition.js:485
for (var attrName in settings) {
if (ko.utils.arrayIndexOf(bindableSettings, attrName) != -1) {
/*
* strategy is unwrapped
*/
settings[attrName] = ko.utils.unwrapObservable(settings[attrName]);
} else {
settings[attrName] = settings[attrName];
}
}
// composition.js:523
if (system.isString(context.strategy)) {
/*
* strategy is loaded
*/
system.acquire(context.strategy).then(function (strategy) {
context.strategy = strategy;
composition.executeStrategy(context);
}).fail(function(err){
system.error('Failed to load view strategy (' + context.strategy + '). Details: ' + err.message);
});
} else {
this.executeStrategy(context);
}
// composition.js:501
executeStrategy: function (context) {
/*
* strategy is executed
* expected to be a promise
* which returns the view to be bound and inserted to the DOM
*/
context.strategy(context).then(function (child) {
composition.bindAndShow(child, context);
});
}