nikhilk / scriptsharp

Script# Project - a C# to JavaScript compiler, to power your HTML5 and Node.js web development.
http://scriptsharp.com
Other
659 stars 182 forks source link

Controlling how the "Constructor" method is created #247

Closed dealproc closed 12 years ago

dealproc commented 12 years ago

@michaelaird and I are chatting back and forth via email about this a bit, and I'm finding he's not come up with a solution, other than using a ton of Script Literals, which I don't like the idea of....

The problem is trying to get a "Validation" class going... e.g., you'd have an abstract class called:

public abstract class ValidationModel
{
    public bool IsValid() { return false; }
}

and when you implement it with your model, and the resulting *.js is produced, you'd get something to the affect of:

var myViewModel = ko.validatedObservable({
   property1: ko.observable().extend({ required: true }),
   property2: ko.observable().extend({ max: 10 })
});

where you may not necessarily get the extend stuff, but the view model would be created in the proper method where calling {model}.isValid() would work as if you did it in JavaScript natively. Is there any way to do this @nikhilk by creating an abstract class to inherit from, or do we have to extend the base Script# libs somehow to enable this? We're trying to implement a cleaner way to use https://github.com/ericmbarnard/Knockout-Validation

nikhilk commented 12 years ago

I am not sure I understand the question fully, and hence probably not seeing the problem. Wouldn't this work?

public class MyViewModel {
    public Observable<string> Property1;
    public MyViewModel() {
        Property1 = Knockout.Observable<string>().Extend(new Dictionary("required", true));
    }
}

MyViewModel model = KnockoutValidation.ExtendViewModel<MyViewModel>(new MyViewModel());

Assumption:

public static class KnockoutValidation {

    [ScriptAlias("ko.validatedObservable")]
    public static TModel ExtendViewModel<TModel>(TModel model) { return null; }
}
nikhilk commented 12 years ago

If ko.validatedObservable only adds members to the specified view model, rather than returning a new object, you could write the following base class in your app:

public abstract class ValidatedViewModel {
    protected ValidatedViewModel() {
        KnockoutValidation.ExtendViewModel<ValidatedViewModel>(this);
    }
}
dealproc commented 12 years ago

@nikhilk Let me fiddle with this in the next hour, and i'll see what the results are.


(function($) {

Type.registerNamespace('TestingValidation');

TestingValidation.ValidatedViewModel = function TestingValidation_ValidatedViewModel() {
    ko.validatedObservable(this);
}

TestingValidation.ViewModel = function TestingValidation_ViewModel() {
    /// <field name="property1" type="Observable`1">
    /// </field>
    TestingValidation.ViewModel.initializeBase(this);
    this.property1 = ko.observable().extend({ required: true });
}
TestingValidation.ViewModel.prototype = {
    property1: null
}

TestingValidation.ValidatedViewModel.registerClass('TestingValidation.ValidatedViewModel');
TestingValidation.ViewModel.registerClass('TestingValidation.ViewModel', TestingValidation.ValidatedViewModel);
})(jQuery);

Not sure if that'll do the trick, since you're calling TestingValidation.ViewModel.initializeBase(this) before you call on this.property1=ko.observable().extend(..);

Thinking in the constructor of ViewModel, I can, once the properties are set, potentially push this to ko.validatedObservable(), which gives me:

TestingValidation.ViewModel = function TestingValidation_ViewModel() {
    /// <field name="property1" type="Observable`1">
    /// </field>
    this.property1 = ko.observable().extend({ required: true });
    ko.validatedObservable(this);
}
TestingValidation.ViewModel.prototype = {
    property1: null
}

I'll review the documentation for the fluent validation and see if that'll work. if so, brilliant!

dealproc commented 12 years ago

Interesting... the author's fiddle http://jsfiddle.net/ericbarnard/KHFn8/ doesn't do the "new" way... it generates it based on a "group".

dealproc commented 12 years ago

Thinking that this can be avoided by just using the ko.validation.group() method instead.