Creating Knockout Markup within MVC 3

We're in the process of developing a new infrastructure for our MVC client to minimize the need for extensive Javascript coding, especially since most of our developers are primarily working on desktop applications.

One approach I've taken for our knockout scripts is to create an Extension method that can automatically generate all the necessary knockout elements based on the model using reflection. This has been effective for simple models without computed values.

For instance, if we have a class like this:

public class AppViewModel
  {
     public string FirstName {get; set;}
     public string LastName {get; set;}
  }

The script generated and added to the view would look like this:

function AppViewModel() {
    this.firstName = ko.observable('Bob');
    this.lastName = ko.observable('Smith');
}

My goal now is to find a way to also support computed values from the model. For example:

public FullName()
{
    return this.FirstName + " " + this.LastName;
}

This should ideally generate something similar to:

this.fullName = ko.computed(function() {
        return this.firstName() + " " + this.lastName();
    }, this);

In essence, what I'm seeking is a way to generate computed values based on the model structure. Any assistance or suggestions would be greatly appreciated.

Thanks in advance!

Cheers, Steve

Answer №1

Expanding on Pavel's points earlier, there is a perfect example that directly aligns with your specific situation:

Below is an excerpt from the page:

Model:

public class HelloWorldModel
{
  public string FirstName { get; set; }
  public string LastName { get; set; }

  public Expression<Func<string>> FullName()
  {
    return () => FirstName + " " + LastName;
  }
}

Razor:

@using PerpetuumSoft.Knockout
@model KnockoutMvcDemo.Models.HelloWorldModel           
@{
  var ko = Html.CreateKnockoutContext();
}
<p>First name: @ko.Html.TextBox(m => m.FirstName)</p>
<p>Last name: @ko.Html.TextBox(m => m.LastName)</p>
<h2>Hello, @ko.Html.Span(m => m.FullName())!</h2>

@ko.Apply(Model)

Controller:

public class HelloWorldController : BaseController
{
  public ActionResult Index()
  {
    InitializeViewBag("Hello world");
    return View(new HelloWorldModel
    {
      FirstName = "Steve",
      LastName = "Sanderson"
    });
  }
}

Autogenerated Html:

<p>
    First name:
    <input data-bind="value : FirstName" /></p>
<p>
    Last name:
    <input data-bind="value : LastName" /></p>
<h2>
    Hello, <span data-bind="text : FullName"></span>!</h2>

<script type="text/javascript">
    var viewModelJs = { "FirstName": "Steve", "LastName": "Sanderson" };
    var viewModel = ko.mapping.fromJS(viewModelJs);
    viewModel.FullName = ko.computed(function () {
        try {
            return this.FirstName() + ' ' + this.LastName();
        } 
        catch (e) { return null; };
    }, viewModel);
    ko.applyBindings(viewModel);
</script>

Answer №2

Perhaps this resource could be beneficial:

Answer №3

Have you checked out the Script# framework?

Answer №4

Be sure to check out the official examples for Knockout JS at

You can also find helpful tutorials for Knockout JS at

Exploring these resources will greatly assist you in mastering Knockout JS.

Best regards, -Naren

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

clicking on internal links in the bootstrap side menu causes it to jump

Im trying to add a side menu to a help page. The menu and internal links are functioning properly, but when clicked, the side menu partially goes behind the navbar. As a beginner, I'm not sure how to resolve this issue. Can someone offer some guidan ...

Inquiring about the Model component within the MVC architecture in a web application created with NodeJs and integrated with

As a beginner in NodeJs, I am venturing into creating web applications using the express framework and MySQL. Understanding that in MVC architecture, views are represented by *.ejs files, controllers handle logic, and models interact with the database. Ho ...

Continue scanning the expanding page until you reach the end

One of the challenges I am facing is that on my page, when I manually scroll it grows and then allows me to continue scrolling until I reach the bottom. This behavior is similar to a Facebook timeline page. In an attempt to address this issue, I have writ ...

What is the best way to combine two arrays into a single array using AngularJS?

Here is a code snippet: $scope.studentDetails=[]; $scope.studentDetails=[0][id:101,name:one] [1][id:102,name:two] [2][id:103,name:three] $scope.studentMarks=[]; $scope.studentMarks=[0][id:101,marks:78] ...

Is there a way to disable default tooltips from appearing when hovering over SVG elements?

Looking for a way to display an interactive SVG image on an HTML page without default tooltips interfering. While I'm not well-versed in javascript/jQuery, I've managed to implement customized tooltips using PowerTip plugin. However, these custom ...

What is the process for retrieving data from mongoDB and displaying it by year in a single row?

I have received an array of data from MongoDB, which includes id, userName, and date. The date consists of years and months. My goal is to display this data categorized by years. How can I construct a query to the database that will show the data for all y ...

What is the best way to add an array of JSON objects to another array of JSON objects?

The current JSON array obtained from the response is as follows: comments:[{id: "3124fac5-9d3e-4fa9-8a80-10f626fbf141", createdDate: 1469606019000,…},…] 0:{id: "3124fac5-9d3e-4fa9-8a80-10f626fbf141", createdDate: 1469606019000,…} createdBy:{id: "cf2 ...

The HTTP request arrives with no content within the body

I am in the process of developing a basic client-server application using Node and Express. The goal is for the program to receive a JSON input on the client-side, perform some operations, and then send data to the server-side. Currently, I am able to sen ...

Ways to implement a package designed for non-framework usage in Vue

Alert This may not be the appropriate place to pose such inquiries, but I am in need of some guidance. It's more about seeking direction rather than a definitive answer as this question seems quite open-ended. Overview I've created a package th ...

When it comes to optimizing JavaScript, what is the best approach for replacing multiple substrings in a string with various strings?

While working on the code I develop and maintain, I encountered an issue. There is a function in my code that takes a query (in the form of a string) and replaces certain substrings within that string with different ones. For instance, if a user inputs th ...

Error message in React Js indicating the absence of a specified file or directory: "Package.json cannot

When I try to run npm start, I encounter the following error - PS D:\React\operations_app_tut> npm start npm ERR! path D:\React\operations_app_tut\package.json npm ERR! code ENOENT npm ERR! errno -4058 npm ERR! syscall open npm ...

Attempting to display an external webpage within a popup window on my ASP.NET MVC3 application

I am working on an ASP.NET MVC 3 website that needs to display a card validation page in a popup. The challenge is that the card validation page belongs to an external website and cannot be modified. One of the requirements is to make a POST request to thi ...

Issue with Discord.js (14.1) - Message Handling Unresponsive

After developing a sizable Discord Bot in Python, I decided to expand my skills and start learning JS. Despite thoroughly studying the documentation and comparing with my original Python Bot regarding intents, I am facing difficulties getting the message ...

"The incredible power of the spread operator in conjunction with EsLint

Is there a way to duplicate an object and modify one of its properties? Here's an example: const initialState = { showTagPanel: false, }; export default function reducerFoo(state = initialState, action) { switch(action.type) { case types.SH ...

Guide on appending a file to a formData object in vue.js

Having trouble adding the file from the input to the formData object. Even after trying multiple solutions, the object appears to be empty when I log it. Can't seem to figure out what's wrong. File Input: <input class="btn btn-sm btn-rounded ...

Unveil SQL Limit with a Simple Scroll Load

After successfully laying out and creating my website, the next step is to load more results on scroll. This question has been posed numerous times before, but I am curious if there is a simple solution that can seamlessly integrate into my current setup. ...

Utilizing a jQuery variable within an .html() method

Can a Jquery if statement be used to display different content inside a div based on a variable? For example, if the variable is set to "cats", the displayed content might say "I like cats", and if it changes to "dogs", it would read "I like dogs". Is this ...

Utilize the power of jQuery for form validation by combining the errorPlacement and showErrors functions

I am currently attempting to implement validation using the Jquery .validate plugin. Unfortunately, I have encountered an issue where I am unable to utilize both the errorPlacement and showErrors methods simultaneously. If you'd like to see a demons ...

"Instead of seeing the expected content, a blank page is showing

I've been searching for a solution to this problem without any luck. Any assistance would be greatly appreciated. Initially, I created a "tabs" default project which worked fine as a base. However, after making a few modifications, the screen ended u ...

Having difficulty transferring navigation props between screens using react-navigation

Within my ContactList component, I have utilized a map to render various items. Each item includes a thumbnail and the desired functionality is that upon clicking on the thumbnail, the user should be directed to a new screen referred to as UserDetailsScree ...