I've been tasked with adding a feature to an app written by someone who has since left my company. This is implemented with C#/Knockout/Breeze/Durandal. I'm wondering if anyone can answer some of the questions I have regarding the inner workings of knockout and C# interactions:
1) Why is knockout converting an existing ICollection to an observableArray properly, but not a new one that I've added to the model?
2) What is the mechanism that converts the Model to obs/obsArrays? I'm guessing it's got something to do with how the data is pulled back but I'm not sure.
I do not see any js code that would initialize the existing Collection as an observableArray, there's no
vm.existingCollection = ko.observableArray();
He just uses it in is source code as
vm.existingCollection.push(stuff);
Edit to include some code for reference
Here's the model code I'm working with:
public class SimCompare : Report
{
public string LeftGraphName { get; set; }
public int? LeftConsolidationId { get; set; }
public int LeftAsOfDateOffset { get; set; }
public int LeftSimCompareSimulationTypeId { get; set; }
public virtual Consolidation LeftConsolidation { get; set; }
public virtual ICollection<SimCompareSimulationType> LeftSimCompareSimulationTypes { get; set; }
public string RightGraphName { get; set; }
public int? RightConsolidationId { get; set; }
public int RightAsOfDateOffset { get; set; }
public int RightSimCompareSimulationTypeId { get; set; }
public virtual Consolidation RightConsolidation { get; set; }
public virtual ICollection<SimCompareSimulationType> RightSimCompareSimulationTypes { get; set; }
public bool IsQuarterly { get; set; }
public virtual ICollection<SimCompareScenarioType> SimCompareScenarioTypes { get; set; }
}
Then there's a simcompareconfig.js file that starts off like this:
define([
'services/globalcontext',
'viewmodels/simulationselectconfig',
'durandal/app'
],
function (globalContext, simulationselectconfig, app) {
var simCompareVm = function (simCompare) {
var self = this;
this.simCompare = simCompare;
...
There is an existing function to add a scenarioType with a line that looks like this:
simCompare().simCompareScenarioTypes().push(newSimCompareScenarioType);
But that simCompareScenarioTypes() isn't defined anywhere in terms of JS (that I can see). However there is a similar definition in the C# model. This is what's leading me to believe that the model is somehow getting mapped behind the scenes.
Any help is greeeeatly appreciated.
Related
I am having a weird issue with my project. I have 2 models in my project and they are called Job and Jobs. Originally when I started the project it created the tables in SQL as Jobs and Jobs1. I am confused as to why it called the tables these names. When I deleted the tables in SQL and recreated them to add changes I named them Job and Jobs. When I run the project and try to retrieve the data it is telling me it cannot find dbo.Jobs1. I do not have anything in my code that would make entity framework create these tables in the first place. Also my AspNet _Migration table does not exist anymore. I deleted it due to changes and the system usually puts a new one back but it doesn't appear to do this either. Not important to me unless someone can tell me that it will break the system if not there or that the problem I am having is related. I have done a search in the project for dbo.Jobs1 and just Jobs1 and nothing comes up. Could someone direct me as to where to correct this and maybe why it created these tables in that fashion in the first place. Thank you.
These are the models of question in my project:
public class Job
{
public Job()
{
SubJobs = new List<Jobs>();
}
[Key]
public string TopLvlJob { get; set; }
public string Description { get; set; }
public string ExtDescription { get; set; }
public string PartNumber { get; set; }
public string Drawing { get; set; }
public bool UpgradeAvailable { get; set; }
public virtual IEnumerable<Jobs> SubJobs { get; set; }
}
}
public class Jobs
{
public Jobs()
{
Parts = new List<MaterialRequired>();
}
[Key]
public string JobNumber { get; set; }
public string Drawing { get; set; }
public string PartNumber { get; set; }
public string Description { get; set; }
public string ExtDescription { get; set; }
public string TopLvlJob { get; set; }
public bool IsViewable { get; set; }
public virtual IEnumerable<MaterialRequired> Parts { get; set; }
}
I faced a problem. I can't figure out how to post collection with dependency.
I'll show you a code then it maybe clearer what I'm trying to achieve.
I have ViewModel:
public class ProjectViewModel : BaseViewModel
{
public int Id { get; set; }
public string Customer { get; set; }
public string CustomerRepresentative { get; set; }
public string ProjectTitle { get; set; }
public string WWSNumber { get; set; }
public List<Los> Service { get; set; }
}
LosViewModel:
public class Los
{
public int LosNumber { get; set; }
public string Service { get; set; }
public List<Pos> Pos { get; set; }
}
Pos view model:
public class Pos
{
public int PosNumber { get; set; }
public string PosDescription { get; set; }
}
As you see first ViewModel has list. That meens that when user fills LosNumber and enters Service he can add to it PosNumber and PosDescription.
I can't find information how to post with Razor such model.
All I have found is how to display such ModelViewm but not edit.
Maybe somebody had faced this kind of problem ? Any help ?
You need to put the collection into a for loop in your view, then reference the object by index on the collection. MVC is smart enough to figure out that this is a collection when you post it back. Something like...TextBoxFor(m => Model.Service[i].LosNumber). The collection inside a collection will most likely just be a nested for loop.
MVC Razor view nested foreach's model
Example error; I try to Scaffold Controller Region -Repository
Region class
public class Region
{
public int RegionId { get; set; }
public string RegionCode { get; set; }
public string ApiUrl { get; set; }
public Universe[] Universes { get; set; }
}
The error repeats essentially for each file it tries to generate (the views, mostly).
I'm not sure what information to include other than this, because I have no clue what causes it. I've tried searching for a solution, but most solutions seems unrelated to my particular issue.
What I will suggest to you is to replace the Array by a List or better an generic interface ICollection. And then try again. Working with array you need to intialize it in the constructor.
public class Region
{
public int RegionId { get; set; }
public string RegionCode { get; set; }
public string ApiUrl { get; set; }
public ICollection<Universe> Universes { get; set; }
}
I solved the problem immediately after submitting with a last-resort option.
I changed:
public Universe[] Universes { get; set; }
To:
public ICollection<Universe> Universes { get; set; }
Then I ran the Scaffold command again, and it worked perfectly. Strange!
We currently have several underlying database tables such as Events, Shop Products, Content Pages etc. each with have shared properties such as having a Name, a details page on the front end of the site, a thumbnail url, an active flag etc.
I'm trying to figure out the most efficient way of creating a class of shared properties that can be used to pass around these objects generically. An example might be the search results page. The search can be done against the name of the collection of data which is actually across multiple tables originally.
I am struggling using inheritance due to all these classes originating from LINQ classes and I don't want to start editing the datacontext designer to suit my needs.
Currently each partial class on my LINQ classes contains a SharedObject method:
public partial class Event
{
public SharedObject SharedObject
{
get
{
return new SharedObject(this);
}
}
...
This is repeated for Events, Shop Products etc. The Shared Object class contains the following:
public class SharedObject
{
public string Reference { get; set; }
public string Name { get; set; }
public string ImageURL { get; set; }
public bool IsVisible { get; set; }
public bool IsAdminVisible { get; set; }
public string FrontEndDetailsURL { get; set; }
public string AdminDetailsURL { get; set; }
public object OriginalObject { get; set; }
public string ObjectDescription { get; set; }
public SharedObject(object originalObject)
{
if (originalObject.GetType() == typeof(Event))
{
Event eventx = (Event)originalObject;
Reference = eventx.Reference;
Name = eventx.Name;
ImageURL = eventx.ImageURL;
IsVisible = eventx.IsActive && !Event.IsArchived;
IsAdminVisible = !eventx.IsArchived;
FrontEndDetailsURL = eventx.DetailsURL;
AdminDetailsURL = eventx.AdminDetailsURL;
OriginalObject = originalObject;
ObjectDescription = "Event";
}
....
Does this sound like a suitable solution?
Consider using an interface. This is much more flexible.
public interface ISharedObject
{
string Reference { get; set; }
string Name { get; set; }
string ImageURL { get; set; }
bool IsVisible { get; set; }
bool IsAdminVisible { get; set; }
string FrontEndDetailsURL { get; set; }
string AdminDetailsURL { get; set; }
object OriginalObject { get; set; }
string ObjectDescription { get; set; }
}
public partial class Event : ISharedObject
{}
I think the most efficient way to pass around your shared objects is to use the "Chain of responsibility pattern" Chain of responsibility
For the inheritance LINQ you think of the use of IQueryable <T>. I hope that it can help you
I have four MVC model layer domain classes.
namespace MvcMobile.Models.BusinessObject
{
public class Speaker
{
public int SpeakerID { get; set; }
public string SpeakerName { get; set; }
}
public class Tag
{
public int TagID { get; set; }
public string TagName { get; set; }
}
public class Seminar
{
public string Seminar_Code { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Room { get; set; }
}
public class Seminar_Detail
{
public string Seminar_Code { get; set; }
public int SpeakerID { get; set; }
public int TagID { get; set; }
public string DateAndTime { get; set; }
}
}
I would like to make CRUD operation by using these classes. So I create two VeiwModel Classes.
namespace MvcMobile.ViewModel
{
public class Seminar_Root_ViewModel
{
public Seminar_Subsidiary_ViewModel Seminars { get; set; }
public List<Speaker> Speakers { get; set; }
public List<Tag> Tags { get; set; }
}
public class Seminar_Subsidiary_ViewModel
{
public Seminar Seminar { get; set; }
public List<Seminar_Detail> Seminar_Detail { get; set; }
}
}
For Controller layer, I consider that I will use Seminar_Root_ViewModel to make the whole CRUD operation processes.
What I would like to ask is that Is this proper way or correct way?
If you have more elegant way to make model layer and ViewModel layer, Please let me get suggestion.
Every suggestion will be appreciated.
[updated]
Let's assume that I make master-Detail form design.
Speaker and Tag are just look-up tables for dropdownlist or some controls like that.
Seminar is Master Data and Seminar_Detail will be Item Grid Data.
So As for this scenario, all of this classes are needed for this program.
Please let me know if my thinking is wrong.
The only thing I can see is if you are not going to re-use your Seminar_Subsidiary_ViewModel view model you could skip it.
If you are going to need those two properties Seminar and Seminar_Detail on another view or ajax call, it's perfectly fine to have that kind of separation.
Personally I'm not a huge fan of _ on class name, but that have nothing to do with the question.