DuoCode and knockout

I look at DuoCode as an alternative to TypeScript, since it uses C #, which means that my dev can use existing knowledge with C #, but also that we can reuse, for example, the validation logic on both the client and and on the server.

There is currently no binding for the knockout, so I created my own, it's very simple

namespace Knockout
{
    [Js(Name = "ko", Extern = true)]
    public static class Global
    {
        [Js(Name = "observable", OmitGenericArgs = true)]
        public static extern Observable<T> Observable<T>();

        [Js(Name = "observable", OmitGenericArgs = true)]
        public static extern Observable<T> Observable<T>(T value);

        [Js(Name = "computed", OmitGenericArgs = true)]
        public static extern Observable<T> Computed<T>(Func<T> computed);

        [Js(Name = "applyBindings")]
        public static extern void ApplyBindings(object viewModel);

        [Js(Name = "unwrap", OmitGenericArgs = true)]
        public static extern T Unwrap<T>(Observable<T> observable);

    }

    [Js(Name = "ko.observable", Extern = true)]
    public class Observable<T>
    {
        //TODO: Add more methods like subscribe, extend etc
    }
}

Here is a simple model using it

namespace ViewModels
{

    public class FooViewModel
    {
        public FooViewModel()
        {
            Bar = Global.Observable("HelloWorld");
            Computed = Global.Computed(() => Global.Unwrap(Bar) + "COMPUTED");
        }

        public Observable<string> Bar { get; set; }
        public Observable<string> Computed { get; set; }
    }
}

A computational function can use the base observable value using Global.Unwrap, which translates to ko.unwapon the client

But to set the value, I did not find a solid solution, only the resolution I found,

Js.referenceAs<Action<string>>("this.Bar")("New Value");

Who has a path to many shortcomings to be a decision

Any ideas?

edit: , , javascript, Knockout

public static class ObservableExtensions
{
    public static void SetValue<T>(this Observable<T> observable, T value)
    {
        Js.referenceAs<Action<T>>("observable")(value);
    }
}

Yoav answer

  • , referenceAs,
  • JsFunction ,
  • ,

public static class ObservableExtensions
{
    public static void Set<T>(this Observable<T> observable, T value)
    {
        observable.As<Action<T>>()(value);
    }

    public static T Get<T>(this Observable<T> observable)
    {
        return observable.As<Func<T>>()();
    }
}

, ,

Knockout.ObservableExtensions.Set(String, this.get_Bar(), "New value");

this.get_Bar()("New value");

, Observable Arrays,

[Js(Name = "ko.observableArray", Extern = true)]
public class ObservableArray<T> : Observable<JsArray<T>>
{
    [Js(Name = "push", OmitGenericArgs = true)]
    public extern void Push(T value);
}

Global KO

[Js(Name = "observableArray", OmitGenericArgs = true)]
public static extern ObservableArray<T> ObservableArray<T>(T[] values);

, JsArray, IEnumerable ..,

ko.observableArray($d.array(System.Int32, [1, 2, 3, 4]));

, Nockout Javascript.

+4
1

:

  • Js.referenceAs As : Bar.As<Action<string>>()("New Value");
  • - Observable JsFunction, invoke : Bar.invoke("New Value");
  • , , , . :

    public static void Set<T>(this Observable<T> o, T value)
    {
      o.As<Action<T>>()(value);
    }
    

    ( , , Observable extern, ) : Bar.Set("New value");

Bar ( )

(: DuoCode)

Edit

, . , - :

[Js(Name="")]
public void SetValue(T value)

: mscorlib.js, $d.array ( ). , , Int32. , , T, , :

[Js(Name = "observableArray", OmitGenericArgs = true)]
public static extern ObservableArray<T> ObservableArray<T>(object[] values);
+2

All Articles