Knockout, How to add custom functions - javascript

I have this code:
interface KnockoutObservable<T> {
reset() : void;
}
ko.observable.fn.reset = function () {
return ko.pureComputed(function () {
var target = this();
var initialValue = target();
target(null);
target(initialValue);
}, this);
}
In my calling code I have:
public selectedBoxOperator: KnockoutObservable<string>;
And I can now do:
this.selectedBoxOperator.reset();
The function pops-up with intellisence, but it is not executed. It skips the function...(I used the chrome debugger). Any idea how to get this to work? If this will works I can build more "extension" functions like this..

Related

javascript class with event methods

My goal is to make a class with some chained functions, but I'm stuck and hoping for some help. This is what I got:
robin = new batman("myiv");
var batman = (function() {
var me = this;
function batman(id){
me._id=id;
document.getElementById(id).addEventListener('mousemove', me.mouseMoving.bind(me),true);
}
this.mouseMoving = function(){
document.getElementById(me._id).style.background="orange";
}
return batman;
}
And this pseudo code is what I am aiming to get. Basically, pass in the ID of an element in my HTML and chain functions to it such as onclick etc, and whatever code inside there, runs. as in example, changing background colors.
Is it possible?
superman("mydiv"){
.onmouseover(){
document.getElementById(the_id).style.background="#ffffff";
},
.onmouseout(){
document.getElementById(the_id).style.background="#000000";
},
etc...
}
edit: updated with missing code: "return batman;"
You can do method chaining by returning the current object using this keyword
var YourClass = function () {
this.items = [];
this.push = function (item) {
if (arguments) {
this.items.push(item);
}
return this;
}
this.count = function () {
return this.items.length;
}
}
var obj = new YourClass();
obj.push(1).push(1);
console.log(obj.count())
Working sample
https://stackblitz.com/edit/method-chaining-example?file=index.js

how do I call sibling functions in a singleton class?

In the following code, .refresh could call .add, but I get Uncaught TypeError: undefined is not a function
My guess is because it is not defined at the time class is created, but if this is true, without replicating the code, is there a way to call a sibling public function from the same class?
var fileSelector = (function () {
var self = this;
function callback (data,status,xhr) {
$("#File_Selector_Container").html(data);
utils.setItem ("fileSelector", "TRUE");
}
return {
refresh : function () {
if (utils.getItem ("fileSelector") == "TRUE") {
self.add();
}
},
add : function () {
$.get(script_name ,"AddFileSelector",callback,"html");
},
remove : function () {
$("#File_Selector_Container").html("");
}
}
})();
I started this from: Simplest/Cleanest way to implement singleton in JavaScript? and I can't find it now, but another question where I got self=this from.
this (and hence self) simply refers to the global object (i.e. window). That's why you get the error, there is no global add function. I recommend to read the MDN documentation to learn how this works.
One solution is to keep a reference to the object you are returning and use that instead:
var fileSelector = (function () {
function callback (data,status,xhr) {
$("#File_Selector_Container").html(data);
utils.setItem ("fileSelector", "TRUE");
}
var fileSelector = {
refresh : function () {
if (utils.getItem ("fileSelector") == "TRUE") {
fileSelector.add();
}
},
add : function () {
$.get(script_name ,"AddFileSelector",callback,"html");
},
remove : function () {
$("#File_Selector_Container").html("");
}
};
return fileSelector;
})();

Typescript: How to create 'lambda function call' for external method?

The Problem
I am picking up Typescript and just learned that lambda functions are used to (edit) set the value of this. However, I'm not sure how to pass my view model's this into a function that calls another method that I have not defined. In my case, I'm trying to call a Knockout method. See example:
Desired JavaScript:
var MyViewModel = (function () {
function MyViewModel() {
var _this = this;
...
this.someMethod = function () {
ko.utils.arrayForEach(this.array1(), function (item) {
while (item.array2().length < _this.array3.length) {
item.array2.push(12345);
}
});
};
...
Actual JavaScript:
var MyViewModel = (function () {
function MyViewModel() {
var _this = this;
...
this.someMethod = function () {
ko.utils.arrayForEach(_this.array1(), function (item) {
while (item.array2().length < this.array3.length) {
item.array2.push(12345);
}
});
};
...
TypeScript:
method = () => {
ko.utils.arrayForEach(this.array1(), function(item){
while(item.array2().length < this.array3().length){
item.array2.push(0);
}
})
}
One Solution...
One solution I've used was to manually set this.array3().length to _this.array3.length(), but that's pretty hacky and I do not like it.
How should I go about passing the right this into my inner function?
You need to use another lambda to continue the chain of this :
method = () => {
ko.utils.arrayForEach(this.array1(), (item) => { // NOTE here
while(item.array2().length < this.array3().length){
item.array2.push(0);
}
})
}
Tips on this in TypeScript : https://www.youtube.com/watch?v=tvocUcbCupA&hd=1

Handling events inside a class (Prototype)

I am rewriting the question to make it easier to answer (I Hope). I want to have a Button inside a class (prototype) but I want the handler to be in the class also. Works fine if the handler is outside class but cannot find it if within.
Thanks in advance for your help.
function myWindow(message) {
this.SS = SpreadsheetApp.getActiveSpreadsheet();
this.App = UiApp.createApplication();
this.App.setTitle(message);
this.Panel = this.App.createVerticalPanel();
this.App.add(this.Panel);
this.Button = this.App.createButton('OK', this.App.createServerHandler('handler'));
};
myWindow.prototype = {
constructor: myWindow,
handler: function (e)
{
Browser.msgBox('Click');
},
show: function()
{
this.Panel.add(this.Button);
this.SS.show(this.App);
}
};
function Run() {
var theWindow = new myWindow('Hello World');
theWindow.show();
}
The error I get when I click the OK Button is "Script function not found handler"
Ok I have done a lot of reading and although it is not explicitly stated it seems createServerHandler is only designed for global functions and nothing else is provided in the UIAPP. That means what I have asked for cannot be done.
The solution would have to look like
function myWindow(message) {
this.SS = SpreadsheetApp.getActiveSpreadsheet();
this.App = UiApp.createApplication();
this.App.setTitle(message);
this.Panel = this.App.createVerticalPanel();
this.App.add(this.Panel);
this.Button = this.App.createButton('OK', this.App.createServerHandler('handler'));
}
myWindow.prototype = {
constructor: myWindow,
show: function() {
this.Panel.add(this.Button);
this.SS.show(this.App);
}
};
function handler(e) {
Browser.msgBox('Click');
};
function Run() {
var theWindow = new myWindow('Hello World');
theWindow.show();
};
which is not flash but workable.

javascript in ajax asp net control

Here is function that creates javascript objects
public IEnumerable<ScriptDescriptor>
GetScriptDescriptors()
{
ScriptControlDescriptor descriptor = new ScriptControlDescriptor("HierarchyPathControl.PathExplorer", this.ClientID);
descriptor.AddProperty("some_property", "some_value");
yield return descriptor;
}
Here is part of .js file
Type.registerNamespace("HierarchyPathControl");
HierarchyPathControl.PathExplorer = function (element) {
HierarchyPathControl.PathExplorer.initializeBase(this, [element]);
alert("invoked");
}
HierarchyPathControl.PathExplorer.prototype = {
initialize: function () {
HierarchyPathControl.PathExplorer.callBaseMethod(this, 'initialize');
alert("not invoked");
},
..............................
Why second alert invokes only if I remove this line:
descriptor.AddProperty("some_property", "some_value");
Thanks.
Check the error console if you have js error during page initialization. The problem seems to be that you didn't define some_property property in you client side class.
Ensure that you have the following definition of the get/set methods inside your HierarchyPathControl.PathExplorer client side class:
get_some_property = function() {
return this._some_property;
},
set_some_property = function(value) {
if (this._some_property != value) {
this._some_property = value;
this.raisePropertyChanged('some_property');
}
}
Here basically some_property should be the name of the property you want to create.

Categories

Resources