KnockoutJS - Data binding error - javascript

I'm new to KnockoutJS, I'm using it for a school project which is based on a movie API from where I get data into UI.
This is my app.js where all the javascript code is:
var ViewModel = function() {
var self = this;
self.movies = ko.observableArray;
self.error = ko.observable;
var moviesUri = '/api/movies/';
function ajaxHelper(uri, method, data) {
self.error('');
return $.ajax({
type: method,
url: uri,
dataType: 'json',
contentType: 'application/json',
data: data ? JSON.stringify(data) : null
}).fail(function(jqXHR, textStatus, errorThrown) {
self.error(errorThrown);
});
}
function getAllMovies() {
ajaxHelper(moviesUri, 'GET').done(function(data) {
self.movies(data);
});
}
getAllMovies();
};
ko.applyBindings(new ViewModel());
And this is my index.html where the data is displayed:
#section scripts {
#Scripts.Render("~/bundles/app")
}
<div class="page-header">
<h1>Movie Database API</h1>
</div>
<div class="row">
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">Movies</h2>
</div>
<div class="panel-body">
<ul class="list-unstyled" data-bind="foreach: movies">
<li>
<!--<strong>
<span data-bind="text: DirectorName"></span>
</strong>:--> <span data-bind="text: Title"></span>
<small>
Details
</small>
</li>
</ul>
</div>
</div>
<div class="alert alert-danger" data-bind="visible: error">
<p data-bind="text: error"></p>
</div>
</div>
<div class="col-md-4">
<!-- TODO: Movie details -->
</div>
<div class="col-md-4">
<!-- TODO: Add new movie -->
</div>
</div>
I checked the code and it seems fine, but when I run my application I get into console this:
Uncaught ReferenceError: Unable to process binding "foreach: function
(){return movies }" Message: Unable to process binding "text: function
(){return Title }" Message: Title is not defined
Can someone point me to the right direction and tell me what am I doing wrong?
Thanks.

You are missing parenthesis in your observables declarations:
var ViewModel = function() {
var self = this;
self.movies = ko.observableArray();
//^^ here
self.error = ko.observable();
//^^ here
//...
}
Besides, beware that the properties of your observableArray will not be made observables by default (you might want to look into the mapping plugin).

Related

Alpacajs form data not submitting if user does not tab off textbox

I am having an issue with alpacajs form not submitting data from a textbox if the user does not tab off the textbox before clicking the submit button, if the user has 5 fields to fill out all but the last one is included in the json results.
<div class="panel-group" id="accordian" role="tablist">
<div class="panel-placeholder"></div>
</div>
<div>
<button class="btn btn-default" type="submit">Submit</button>
</div>
<script id="panel-template" type="text/x-handlebars-template">
{{#each panels}}
<div class="panel panel-primary">
<div class="panel-heading">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion" href="#{{panelId}}">
{{title}}
</a>
</h4>
</div>
<div id="{{panelId}}" class="panel-collapse collapse in">
<div class="panel-body">
{{#each sections}}
<div id={{formId}}></div>
{{/each}}
</div>
</div>
</div>
{{/each}}
</script>
and the js code
function onData(formData) {
var friendlyData = "";
// Grab the template script
var templateScript = $("#panel-template").html();
// Compile the template
var compiledTemplate = Handlebars.compile(templateScript);
var compiledHtml = compiledTemplate(formData);
// Add the compiled html to the page
$('.panel-placeholder').html(compiledHtml);
//submit all data
$("[type='submit']").click(function () {
var postData = {
data: JSON.stringify(formData),
friendlyData: friendlyData,
storeData: storeData,
origUrl: origUrl
}
$.ajax({
url: apiUrl + "submit/",
data: postData,
dataType: 'json',
type: 'POST',
success: function (data) {
alert("Data was saved");
},
error: function (err) {
alert(err.statusText);
}
});
});
}
Any help with this would be great, I have not been able to find a solution.
Thank you

Generate and track same template multiple times using Knockout in MVC view?

I put together a Contacts prototype MVC application that uses Knockoutjs. I'm fairly new to Knockout and was wondering if my design is correct in reaching my end goal. My end goal is basically to take an MVC Model that is passed to my Contacts view to start and achieve the following:
Mapping it to my KO Viewmodel.
Use Bootstrap Modal Popup to input my contact data.
Upon Clicking Add in Bootstrap Modal call template after posting JSON
data to controller successfully and have it display under
Edit button on each template rendered under div if clicked brings up same Modal Popup to edit that templates data.
Here's the code breakdown of what I have currently in place.
View Code
<h2>Contacts List</h2>
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-10"><h3>KO Results</h3></div>
</div>
<br />
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-10"><div id="koResults" data-bind="template: { name: 'contactSectionTmp', foreach:Contacts }"></div></div>
</div>
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-10"><strong>Add</strong></div>
</div>
#*I enter data in my bootstrap modal shown below and when I click "Add" the Template below appears
in div element koResults with the data I just entered. This is the desired effect I'm looking for. *#
<div class="modal" id="contactModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header" style="background-color:#B8E28D; border-color: black">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Add Contact</h4>
</div>
<div class="form-horizontal">
<form id="contactModalForm" data-bind="with:newContact,submit:add">
<div class="modal-body">
<h4>Contact</h4>
<div class="form-group">
<label class="col-sm-4 control-label">Name:</label>
<div class="col-sm-8">
<input type="text" name="Name" class="form-control" data-bind="value: Name" />
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">Address:</label>
<div class="col-sm-8">
<textarea rows="4" cols="50" name="Address" class="form-control" data-bind="value: Address"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">Phone:</label>
<div class="col-sm-8">
<input type="text" name="Phone" class="form-control" data-bind="value: Phone" />
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" id="formSubmitContact" class="btn btn-success">Add</button>
<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
</div>
</form>
</div>
</div>
</div>
</div>
#section scripts
<script type="text/javascript" src="~/Scripts/knockout-3.4.0.debug.js"></script>
<script type="text/javascript" src="~/Scripts/knockout.mapping-latest.debug.js"></script>
#* Knockout Template *#
<script id="contactSectionTmp" type="text/html">
<div class="row">
<div class="col-lg-3">Name:</div>
<div class="col-lg-9" data-bind="text: name"></div>
</div>
<div class="row">
<div class="col-lg-3">Address:</div>
<div class="col-lg-9" data-bind="text: address"></div>
</div>
<div class="row">
<div class="col-lg-3">Phone:</div>
<div class="col-lg-9" data-bind="text: phone"></div>
</div>
</script>
End Section
Controller Code
Pass in model to view here.
public ActionResult ContactsList()
{
ContactsVM mData = new ContactsVM();
mData.Contacts = new List<Contact>(){ new Contact { ID = 1, Name="Drew Lucacca", Address="782 Select St.", Phone="421-821-9101"},
new Contact {ID = 2, Name="Kevin Rosassa", Address = "222 Potter Lane", Phone="421-982-5222" },
new Contact {ID = 3, Name="Tim Kropp", Address = "440 PPG Place", Phone="725-434-8989"} };
return View(mData);
}
[HttpPost]
public ActionResult ContactCreate(Contact newContact)
{
var res = newContact;
ContactsVM myContacts = new ContactsVM();
myContacts.Contacts = new List<Contact>();
myContacts.Contacts.Add(new Contact { ID = 4, Name = "Santa Claus", Address = "440 Trump Plaza", Phone = "774-489-8989" });
return Json(myContacts);
}
Javascript Code
` //Main ViewModel
function ContactsVM(data) {
var self = this;
var mapping = {
'Contacts': {
create: function(options) {
return new Contact(options.data);
}
}
};
ko.mapping.fromJS(data, mapping, self);
self.newContact = ko.observable();
self.addContact = function() {
debugger;
self.newContact(new Contact({Name: '', Address: '', Phone: ''}));
}
self.add = function () {
debugger;
var jsData = data;
var jsData1 = ko.mapping.toJSON(self.newContact());
$.ajax({
url: '#Url.Action("ContactCreate", "Home")',
type: 'POST',
data: ko.mapping.toJSON(self.newContact()),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function (jsonObject) {
self.contacts.push(new Contact(jsonObject));
}
});
// Close the modal.
$('#contactModal').modal('toggle');
};
self.cancel = function () {
// Close the modal.
$('#contactModal').modal('toggle');
};
//self.resetForm = function (formId) {
// var form = $('#' + formId);
// form.validate().resetForm();
// form.get(0).reset();
//};
};
function Contact(data) {
ko.mapping.fromJS(data, {}, this);
this.isEdit = ko.observable(false);
};
$(function () {
var jsonModel = #Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model));
var vm = new ContactsVM(jsonModel);
ko.applyBindings(vm);
});
Contact Entity
public class Contact
{
public int ID { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
}
ContactsVM Entity
public class ContactsVM
{
public List<Contact> Contacts { get; set; }
}
EDIT #1
See here's the thing I know that the javascript isn't correct and note that in javascript comments asking if you can help me identify if it isn't correct how should it be.
I moved the code to new location at bottom of MVC view for the Javascript code didn't seem to find model.
Javascript - Knockout - Mapping Error
JavaScript runtime error: 'push' is undefined
self.contacts.push(new Contact(jsonObject)); < --- Error happens here.
Any help here would be greatly appreciated and I'm sure would help others as well.
I think it might be best for you to take an iterative approach at getting this working, based on the steps you have listed. Do one thing at a time, get it working, then move on to the next item. Trying to work out everything at once and test it altogether is really tough.
First Recommendation: Make your client-side models reflect your server-side models. After that, things just get easier. Since you are using ko mapping, your client-side model setup gets easier:
function ContactsVM(data) {
var mapping = {
'Contacts': {
create: function(options) {
return new Contact(options.data);
}
}
};
ko.mapping.fromJS(data, mapping, this);
this.newContact = ko.observable();
}
function Contact(data) {
ko.mapping.fromJS(data, {}, this);
this.isEdit = ko.observable(false);
}
Then you can create and apply the top-level view model fairly easily as well:
var vm = new ContactsVM(jsonModel);
ko.applyBindings(vm);
This gives you a top-level viewmodel with a fully filled Contacts observable array property. You can use the newContact property for your modal to add a new contact, just fill it with a new Contact instance.
new Contact({Name:'', Address:'', Phone:''})
When you push this new contact to the array of contacts, the DOM will automatically update to display the new contact, so you won't need to use the "ko.renderTemplate" logic that you specified. I imagine you could also show/hide the modal based on if this observable has a value if you wanted to.
Second recommendation: Try doing things with knockout first, and if you can't then use jQuery. I would not recommend using jQuery to serialize form values. Remember, you have direct access to client-side models, so you are no longer dependent upon the DOM. The ko mapping plugin has a method to unmap back to a regular JS object.

Not getting all values in View when binding children properties of observable

In my knockout bound view I am not getting all values.
This is my script file:
var ViewModel = function () {
var self = this;
self.games = ko.observableArray();
self.error = ko.observable();
self.detail = ko.observable();
var gamesUri = '/api/games/';
self.getGameDetail = function (item) {
ajaxHelper(gamesUri + item.Id, 'GET').done(function (data) {
self.detail(data);
});
console.log(self.detail);
};
function ajaxHelper(uri, method, data) {
self.error('');
return $.ajax({
type: method,
url: uri,
dataType: 'json',
contentType: 'application/json',
data: data ? JSON.stringify(data) : null
}).fail(function (jqXHR, textStatus, errorThrown) {
self.error(errorThrown);
});
}
function getAllGames() {
ajaxHelper(gamesUri, 'GET').done(function (data) {
self.games(data);
});
}
getAllGames();
};
ko.applyBindings(new ViewModel());
This is my view:
<div class="row">
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">Games</h2>
</div>
<div class="panel-body">
<ul class="list-unstyled" data-bind="foreach: games">
<li>
<strong><span data-bind="text: DeveloperName"></span>:<span data-bind="text: Title"></span></strong>
<small>Details</small>
</li>
</ul>
</div>
</div>
<div class="alert alert-danger" data-bind="visible: error"><p data-bind="text: error"></p></div>
</div>
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading"><h2 class="panel-title">Details</h2></div>
</div>
<table class="table">
<tr><td>Developer</td><td data-bind="text: detail().DeveloperName"></td></tr> //Only this value is displayed
<tr><td>Title</td><td data-bind="text: detail().Title"></td></tr>
<tr><td>Price</td><td data-bind="text: detail().Price"></td></tr>
<tr><td>Genre</td><td data-bind="text: detail().Genre"></td></tr>
<tr><td>Year</td><td data-bind="text: detail().Year"></td></tr>
</table>
</div>
<div class="col-md-4">
</div>
</div>
The problem is it only displays DeveloperName in the view. Title, Price, Genre and Year are not dispayed in the view. I tried many things but I don't know where the error is.
There are two approaches.
The easiest one is to use the with or template binding. The technique is similar, but I'll show an example with the with binding:
<table class="table" data-bind="with: details">
<tr><td>Developer</td><td data-bind="text: DeveloperName"></td></tr>
<tr><td>Title</td><td data-bind="text: Title"></td></tr>
<tr><td>Price</td><td data-bind="text: Price"></td></tr>
<tr><td>Genre</td><td data-bind="text: Genre"></td></tr>
<tr><td>Year</td><td data-bind="text: Year"></td></tr>
</table>
With this technique, whenever you change the object inside the details observable, the new values are applied to the children elements inside the elment which has the with binding. In this case all the elements inside the table element. Besides, the syntax is shorter and more clear. NOTE: you must can use $parent, $parents[] or $root if you need to bind something outside the object bound with with.
The hardest one, which is only neccessary if your viewmodel is more complex and has, for example, computed observables, you need to create an object whose properties are also observables. In this case you bind this object once, and, on the next occasions, you update the innser obervable properties, instead of changing the object itself.
For your example, you must create an object which has all its properties, like DeveloperName, Title, Price, etc. defined as observables. Then you must map the values recovered by AJAX to this properties, which you can do by hand, doing details().DeveloperName(newDetails.DeveloperName), and so on, or using the ko.mapping plugin.
Important note: if you use this technique you must keep the original details bound object, and update its properties. If you substitute the details object itself with a new one, the binding will be lost, and will stop working as desired.
Another note: you cannot use cleanNodes for what you think. Please, see this Q&A.

angularjs - Trouble getting data from database within template file

I'm working on a blog like structured web app In AngularJS. Im trying to retrieve the user which is an other of a post and retrieve their display name dynamically as it loops through all the posts but I cant seem to retrieve data correctly.. This is what I have done so far.
Blog Controller:
uno.controller('newsCtrl', function($scope, $http, adbFactory){
$scope.derp = 'derp!!!!!';
adbFactory.get($http, 'get users 1', false).success(function(data){
$scope.user = data;
}).error(function(){
console.log('Errorrr');
});
$scope.init = function(){
adbFactory.get($http, 'get all blog_posts', true).success(function(data){
$scope.posts = data;
console.log($scope.posts);
});
};
$scope.getAuthor = function(_id) {
adbFactory.get($http, 'get users id ' +_id+ ' spec', false).success(function(data){
//$scope.author = data;
//console.log($scope.author);
return data;
});
};
});
If I console.log the data it shows the users perfectly given the author id which is in the database, but when i attempt to call the getAuthor function using the '{{ }}' scope i get a collage of errors... heres my blog template below.
Blog Template:
<div class="large-12 small-12 columns" ng-init="init()">
<div class="row">
<div class="large-12 small-12 columns" ng-repeat="topic in posts" style="margin-bottom:20px;">
<div id="news-post" class="panel animated fadeInUp">
<div class="row" ng-init="getAuthor(topic.author_id)">
<div class="large-2 small-2 columns">
<img src="{{ topic['thumb'] }}" alt="" style="border-radius:50%; height:100px; width: 150px;" />
</div>
<div class="left large-10 small-10 columns">
<div class="row">
<h2 class="post-title">{{topic['title']}} <p>Posted By, {{ getAuthor(topic.author_id).email }}</p></h2>
<p>{{ topic['body'] }}</p>
</div>
</div>
</div>
</div>
</div>
<hr>
</div>
</div>
not quite sure what the problem can be.. Any thing I'm missing?
UPDATE::
I recently updated my controller and factories to get a better scope of handling my data flow, my Controller now looks like this:
uno.controller('newsCtrl', function($scope, $http, adbFactory, $cacheFactory, unoFunctions){
$scope.init = function(){
adbFactory.get($http, 'get all blog_posts', true).success(function(data){
$scope.posts = data;
$scope.getUser = function(_id) {
$scope.userData = unoFunctions.getUser(_id);
//console.log($scope.userData);
return $scope.userData;
};
});
$scope.getTags = function(_id) {
var post = unoFunctions.getPost(_id);
var _tags = post.tags.split(',');
for(var i = 0; i < _tags.length; i++)
{
_tags[i] = _tags[i].trim();
}
return _tags;
};
$scope.getUserName = function(_id) {
$scope.userData = unoFunctions.getUser(_id);
return $scope.userData.display_name;
};
$scope.getUser = function(_id) {
$scope.userData = unoFunctions.getUser(_id);
//console.log($scope.userData);
return $scope.userData;
};
$scope.getUserName = function(_id) {
$scope.userData = unoFunctions.getUser(_id);
return $scope.userData.display_name;
};
};
});
the unoFunctions factory is wht I use now to handle certain requests from my database, and that is shown below.
uno.factory('unoFunctions', function(adbFactory, $http, $cacheFactory){
var fact = {};
var user = $cacheFactory('user');
var post = $cacheFactory('post');
fact.getUser = function(_id) {
if(!user.get(_id)){
adbFactory.get($http, 'get users id '+_id+' spec', false).success(function(data){
user.put(_id, data);
});
}
return user.get(_id);
};
fact.getPost = function(_id) {
if(!post.get(_id))
{
adbFactory.get($http, 'get blog_posts id '+_id+' spec', false).success(function(data){
post.put(_id, data);
});
}
return post.get(_id);
};
fact.loggedIn = function()
{
console.log('gfdg');
};
/*------------------------------*/
return fact;
});
And my template to output the result is this:
<div class="large-12 small-12 columns" ng-init="init()">
<div class="row">
<div class="large-12 small-12 columns" ng-repeat="topic in posts | filter:postTitle | orderBy:'-time' " style="margin-bottom:20px;">
<div id="news-post" class="panel animated fadeInUp" ng-init="getTags(topic.id)">
<div class="row" style="padding-bottom:0px;">
<div class="large-2 small-2 columns">
<img src="{{ topic['thumb'] }}" alt="" style="border-radius:50%; height:120px; width: 200px;" />
</div>
<div class="left large-10 small-10 columns">
<div class="row" style="padding-bottom:0px;">
<h2 class="post-title">
<a href="#/news/post/{{ topic['id'] }}">
{{topic['title']}}
</a>
<p style="font-size:13px; font-style:italic; color:#a5a5a5" class="right">{{ topic.time | timeago }} {{ }}</p>
<p style="font-weight:bold; font-style:italic; color:#aaa">Posted By, {{ getUser(topic.author_id).display_name }}</p></h2>
<p>{{ topic['body'] }}</p>
<div ng-repeat="tag in getTags(topic.id)"><span style="background:#ccc; margin:7px; padding:4px; border-radius:5px; font-size:12px" class="left">{{ tag }}</span></div>
<p class="right" style="background:#dedede; font-size:13px; padding:7px; border-radius:6px; color:#1985A1;">{{ topic.category }}</p
</div>
</div>
</div>
</div>
</div>
</div>
</div>
This works fine and returns the required results I'm looking for but I wish to get rid of the countless Error: [$rootScope:infdig] errors and keep my console clean.. I researched the error and it seems to be because when I call functions from the unoFunctions factory like, getUser, or getPost. it returns a new array each time or something like that which I guess throws things out of scope. I'm not entirely sure, and reason for this?
This binding
<p>Posted By, {{ getAuthor(topic.author_id).email }}</p>
assumes that getAuthor returns an object, but it doesn't, even with proper return statement - because asynchronous request takes place, and adbFactory chain will apparently return a promise, not an object. And doing adbFactory.get every time getAuthor bindings are being watched would be bad performance-wise - json result has to be parsed constantly, even with $http cache.
A suitable solution for caching and binding service results to the scope (and a precursor to full-blown model) is
var authors = $cacheFactory('authors');
$scope.getAuthor = function(_id) {
if (!authors.get(_id)) {
authors.put(_id, {});
adbFactory.get($http, 'get users id ' +_id+ ' spec', false).success(function(data){
authors.put(_id, data);
});
}
return authors.get(_id);
};

Undefined property knockout.js + mvc

I have a masterDetails view that I populate with some data from a db (it populates fine). I added a button to the master details view, to add a step to my workflow.
My Viewmodel:
/// <reference path="_references.js" />
var viewModel = function (data) {
var self = this;
self.SelectedWorkflow = ko.observable({
Steps: ko.observableArray([]),
Name: ko.observable("")
});
self.Workflows = ko.observableArray(data);
self.addStep = function() {
self.Steps.push(new Step(SelectedWorkflow, "Assignment here", "01/01/2014", "dd:mm:ss", "mail"));
};
};
function Step(workflow,assignment, enddate, reminder, mailaddresses, type) {
var self = this;
self.Workflow = workflow;
self.StepNumber = 0;
self.Assignment = assignment;
self.Enddate = enddate;
self.Reminder = reminder;
self.MailAddresses = mailaddresses;
self.Type = type;
};
/// <reference path="workflowdetails-vm.js" />
$(document).ready(function () {
$.ajax({
url: "/WorkflowDetails/Index/",
type: "POST",
data: {},
success: function (data) {
var workflowlist = ko.mapping.fromJS(data.Workflows);
vm = new viewModel(workflowlist);
ko.applyBindings(vm);
}
});
$(".right-aligned-section").hide();
});
$(document).delegate(".show-details", "click", function () {
$(".right-aligned-section").fadeIn();
var workflow = ko.dataFor(this);
vm.SelectedWorkflow(workflow);
});
My View:
<div class="left-aligned-section">
<ul data-bind="foreach: Workflows()">
<li>
<div class="workflow-item-border">
<div>
<label data-bind="text: Name"></label>
</div>
<div>
<label data-bind="text: StartDate"></label>
</div>
<div>
Show Details
</div>
</div>
</li>
</ul>
</div>
<div class="right-aligned-section" data-bind="with: SelectedWorkflow">
<div class="steps-header">
<div class="left-aligned-div"><strong>Steps for </strong></div>
<div class="left-aligned-div" data-bind="text: Name"></div>
</div>
<button data-bind="click: addStep">add step</button>
<ul data-bind="foreach: Steps">
<li>
<div class="step-item-border">
<div>
<div class="step-label">Stepnumber: </div>
<div style="font-weight: bold" data-bind="text: StepNumber"></div>
</div>
<div>
<div class="step-label">Assignment: </div>
<div style="font-weight: bold" data-bind="text: Assignment"></div>
</div>
<div>
<div class="step-label">Mails: </div>
<div style="font-weight: bold" data-bind="text: MailAddresses"></div>
</div>
<div>
<div class="step-label">End Date: </div>
<div style="font-weight: bold" data-bind="text: Enddate"></div>
</div>
<div>
<div class="step-label">Type: </div>
<div style="font-weight: bold" data-bind="text: Type"></div>
</div>
</div>
</li>
</ul>
</div>
When I press the button - nothing happens. The error I receive is:
ReferenceError: Steps is not defined
I know what it means, but I'm not proficient enough in web development to actually fix it. Please help.
Probably this would work:
var viewModel = {};
viewModel.SelectedWorkflow = {
Steps: ko.observableArray([]),
Name: ko.observable("")
};
viewModel.Workflows = ko.observableArray(data);
viewModel.addStep = function () {
viewModel.SelectedWorkflow.Steps.push(
new Step(SelectedWorkflow, "Assignment here", "01/01/2014", "dd:mm:ss", "mail"));
}
}
You have forgotten about SelectedWorkflow.Steps I think...
Looks like you forgot a this before the Steps.push....
Edit: I have made some further changes to the click handler function
var viewModel = function (data) {
this.SelectedWorkflow = ko.observable({
Steps: ko.observableArray([]),
Name: ko.observable("")
});
this.Workflows = ko.observableArray(data);
this.addStep = function (selectedWorkflow) { // the current context is passed in from the click data-bind
selectedWorkflow.Steps.push(new Step(selectedWorkflow, "Assignment here", "01/01/2014", "dd:mm:ss", "mail"));
}
}
Edit: Fixed code

Categories

Resources