我正在使用knockoutjs映射插件将我的viewmodel映射到json,但它需要大约1分钟的时间。映射后,json文件的大小约为275kb。下面是一个数据样本,我有30个长度的数组,每个包含这么多的数据。将数据传递给viewmodel时,我会像 ko.mapping.toJSON(data)那样访问详细信息,请访问
$( document ).ready( function ()
{
window.Data = ko.mapping.fromJS( data, dataMapping );
if ( localStorage.viewModels == null )
{
console.log( "no data foud in localstorage" );
window.CurrentViewModel = new ViewModel();
ko.applyBindings( window.CurrentViewModel );
localStorage.Data = ko.mapping.toJSON( window.Data );
}
else
{
console.log( 'load required view called' );
Util.LoadRequiredView();
}
} );
function ViewModel()
{
var self = this;
self.CurrentView = ko.observable( 'start' );
self.PreviousView = ko.observable( 'start' );
self.LoginFocus = ko.observable( false );
self.IsHomeViewVisited = ko.observable( false );
self.PartScrollPosition = ko.observable( 0 );
self.IsHomeHover = ko.observable( false );
self.HomeHover = function ()
{
self.IsHomeHover( !self.IsHomeHover() );
}
self.PartOnScroll = function ()
{
self.PartScrollPosition( $( '.tab-section' ).scrollTop() );
}
function GotoView( view )
{
//store the current view in previous view for back buttons
if ( currentSound != null )
{
currentSound.stop();
}
self.PreviousView( self.CurrentView() );
self.CurrentView( view );
if ( view == 'home' )
{
$( '.tab-section' ).scrollTop( self.PartScrollPosition() )
}
}
self.StartClick = function ()
{
GotoView( 'login' );
self.LoginFocus( true );
}
self.LicenseClick = function ()
{
GotoView( 'license' );
}
self.UserName = ko.observable( null );
self.CleaUserNameClick = function ()
{
self.UserName( null );
}
self.Rules = window.Data.Rules;
self.Parts = ko.observableArray();
self.CurrentPart = ko.observable( null );
self.ContinueClick = function ()
{
if ( self.UserName() != null )
{
if ( self.Parts().length == 0 )
{
AddPartToParts();
}
self.CurrentPart( self.Parts()[0] );
GotoView( 'home' );
if ( !self.IsHomeViewVisited() )
{
self.IsHomeViewVisited( true );
var sound = new buzz.sound( 'audio/HomeScreen.ogg' );
sound.play();
}
}
}
function AddPartToParts()
{
var startIndex = 0;
var endIndex;
for ( var i = 1; i <= self.Rules().length / 7; i++ )
{
if ( i % 2 == 0 )
{
endIndex = startIndex + 7;
}
else
{
endIndex = startIndex + 6;
}
if ( endIndex >= self.Rules().length )
{
endIndex = self.Rules().length-1;
}
self.Parts.push( { Id: ko.observable( self.Parts().length + 1 ), Rules: ko.observableArray( self.Rules.slice( startIndex, endIndex+1 ) ) } )
startIndex = endIndex+1;
}
}
function AddExtraPropertiesToRules( rules )
{
for ( var i = 0; i < rules.length; i++ )
{
rules[i].NoOfErrorAttempted = ko.observable( 0 );
rules[i].NoOfErrorFound = ko.observable( 0 );
rules[i].NoOfRuleAttempted = ko.observable( 0 );
rules[i].NoOfRuleFound = ko.observable( 0 );
rules[i].IsVisited = ko.observable( false );
AddExtraPropertiesToActivity( rules[i] );
}
}
AddExtraPropertiesToRules( self.Rules() );
self.PartClick = function ( part )
{
self.CurrentActivity( null );
self.CurrentRule( null );
self.CurrentPart( part );
};
//handle restart click in home view
self.RestartMenuClick = function ()
{
GotoView( 'restart' );
};
self.RestartButtonClick = function ()
{
localStorage.clear();
window.location.reload();
};
self.UserMenuClicked = ko.observable( false );
self.UserMenuClick = function ()
{
ResetMenuClick();
self.UserMenuClicked( true );
};
self.NewUserMenuClick = function ()
{
GotoView( 'newUser' );
};
self.EditNameMenuClick = function ()
{
GotoView( 'login' );
self.LoginFocus( true );
}
self.AboutClicked = ko.observable( false );
self.AboutClick = function ()
{
ResetMenuClick();
self.AboutClicked( true );
}
//reset the menu if the user click any where in the home view
self.AnyWhereClick = function ()
{
ResetMenuClick();
}
self.AboutTheseActivityClick = function ()
{
GotoView( 'aboutTheseActivity' )
}
self.OtherProductsClick = function ()
{
GotoView( 'otherProducts' )
}
self.PrintInstructionsClick = function ()
{
GotoView( 'printInstructions' )
}
self.HowToPlayClick = function ()
{
GotoView( 'howToPlay' );
}
//hide the other menu that are open
function ResetMenuClick()
{
self.AboutClicked( false );
self.UserMenuClicked( false );
}
self.BackButtonClick = function ()
{
GotoView( self.PreviousView() );
}
var currentActivityIndex;
self.CurrentRule = ko.observable( null );
self.GotoActivity = function ( rule, activityIndex )
{
if ( activityIndex != currentActivityIndex )
{
//reset values if current activity
//and next activity is different
ResetCurrentValues();
}
self.CurrentRule( rule );
currentActivityIndex = activityIndex;
SetCurrentActivity( activityIndex );
self.IsLessonFromActivity( false );
GotoView( 'activity' );
ShowAnimation();
};
self.CurrentActivity = ko.observable( null );
self.IsLastACtivity = ko.observable( false );
//added some extra property to activity
function AddExtraPropertiesToActivity( rule )
{
var Activities = rule.Activities();
for ( var i = 0; i < Activities.length; i++ )
{
if ( Activities[i].ImageUrl == null )
{
Activities[i].ImageUrl = ko.observable(
//set the activity image url based on rule and current part
'images/ActivityImages/Activity' + rule.Id() + '.' + Activities[i].Id() + '.png'
);
}
//stores the types of error present in the activity
if ( Activities[i].ErrorTypes == null && rule.IsReview() )
{
Activities[i].ErrorTypes = ko.observableArray();
}
AddTypesOfErrorToActivity( Activities[i] );
if ( Activities[i].CurrentSection == null )
{
Activities[i].CurrentSection = ko.observable( null );
}
if ( Activities[i].IsCompleted == null )
{
Activities[i].IsCompleted = ko.observable( false );
}
if ( Activities[i].IsReviewMode == null )
{
Activities[i].IsReviewMode = ko.observable( false );
}
if ( Activities[i].IsErrorReviewClicked == null )
{
Activities[i].IsErrorReviewClicked = ko.observable( false );
}
if ( Activities[i].IsShowErrorClicked == null )
{
Activities[i].IsShowErrorClicked = ko.observable( false );
}
if ( Activities[i].NoOfErrorAttempted == null )
{
Activities[i].NoOfErrorAttempted = ko.observable( 0 );
}
if ( Activities[i].NoOfAttempts == null )
{
Activities[i].NoOfAttempts = ko.observable( 0 );
}
if ( Activities[i].NoOfErrorFound == null )
{
Activities[i].NoOfErrorFound = ko.observable( 0 );
}
if ( Activities[i].NoOfRuleIdentified == null )
{
Activities[i].NoOfRuleIdentified = ko.observable( 0 );
}
if ( Activities[i].AnsColors == null )
{
Activities[i].AnsColors = ko.observableArray();
}
if ( Activities[i].NoOfErrorPresent == null )
{
Activities[i].NoOfErrorPresent = ko.observable( GetNoOfErrorInActivity( Activities[i] ) )
}
}
}
function AddTypesOfErrorToActivity( activity )
{
for ( var i = 0; i < activity.Sections().length; i++ )
{
if ( activity.Sections()[i].ErrorType )
{
var errortype = ko.utils.arrayFirst( activity.ErrorTypes(), function ( errorType )
{
//alert(errorType.Name);
return activity.Sections()[i].ErrorType.RuleId() == errorType.RuleId();
} );
if ( !errortype )
{
activity.ErrorTypes.push( { RuleId: activity.Sections()[i].ErrorType.RuleId, Name: activity.Sections()[i].ErrorType.Name, AnsColors: ko.observableArray( ["#FFFFFF"] ) } )
}
else
{
errortype.AnsColors.push( "#FFFFFF" );
}
}
}
}
function GetNoOfErrorInActivity( activity )
{
var errorCount = 0;
for ( var i = 0; i < activity.Sections().length; i++ )
{
if ( activity.Sections()[i].IsError() )
{
errorCount = errorCount + 1;
activity.AnsColors.push( '#FFFFFF' );
}
}
return errorCount;
}
function AddExtraPropertiesToSection( activity )
{
var Sections = activity.Sections();
for ( var i = 0; i < Sections.length; i++ )
{
if ( Sections[i].Color == null )
{
Sections[i].Color = ko.observable( 'black' );
}
if ( Sections[i].IsClicked == null )
{
Sections[i].IsClicked = ko.observable( false );
}
if ( Sections[i].IsAnswered == null )
{
Sections[i].IsAnswered = ko.observable( false );
}
if ( Sections[i].TextSize == null )
{
Sections[i].TextSize = ko.observable( 'normal' );
}
}
}
function SetNoOfErrorPresentInActivity( activity )
{
activity.NoOfErrorPresent = ko.observable( 0 );
var Sections = activity.Sections();
for ( var i = 0; i < Sections.length; i++ )
{
if ( Sections[i].IsError() )
{
activity.NoOfErrorPresent( activity.NoOfErrorPresent() + 1 );
}
}
}
function SetCurrentActivity( activityIndex )
{
if ( self.CurrentRule().Activities().length - 1 == activityIndex )
{
self.IsLastACtivity( true );
}
else
{
self.IsLastACtivity( false );
}
var activity = self.CurrentRule().Activities()[activityIndex];
AddExtraPropertiesToSection( activity );
SetNoOfErrorPresentInActivity( activity );
self.CurrentActivity( activity );
}
function ResetCurrentValues()
{
clearTimeout( timeOutID );
clearInterval( intervalID );
self.AnimationTimer( 0 );
self.IsHomeHover( false );
//self.IsErrorReviewClicked(false);
}
var isInstructionClicked;
self.ActivityInstructionClick = function ()
{
if ( !self.CurrentActivity().IsCompleted() )
{
isInstructionClicked = true;
self.AnimationTimer( 0 );
ShowAnimation();
}
}
self.LessonFilePath = ko.observable( null );
self.IsLessonFromActivity = ko.observable( false );
self.RuleCaptionClick = function ( ruleName )
{
self.LessonFilePath( 'Lessons/' + ruleName.replace( / /g, '-' ).replace( /,/g, '' ) + '.html' );
self.IsLessonFromActivity( true );
GotoView( 'autoPlayedLesson' );
}
self.PlayLessonVideo = function ( rule )
{
if ( !rule.IsReview() )
{
self.CurrentRule( rule );
self.LessonFilePath( 'Lessons/' + rule.Caption().replace( / /g, '-' ).replace( /,/g, '' ) + '.html' );
GotoView( 'autoPlayedLesson' );
}
}
self.GoToCurrentActivity = function ()
{
self.IsLessonFromActivity( false );
GotoView( 'activity' );
}
self.HomeClick = function ()
{
self.IsLessonFromActivity( false );
ResetCurrentValues();
GotoView( 'home' );
}
self.Attempts = ko.observable( 0 );
self.IsQuestionView = ko.observable( false );
self.NoOfRuleIdentified = ko.observable( 0 );
function ShowQuestionView( section )
{
self.CurrentActivity().CurrentSection( section );
self.IsQuestionView( true );
//make the Question readonly
ChangeQuestionReadOnlyState( true );
}
self.ErrorClick = function ( section )
{
//if sound is already played and not in question view
if ( ( self.AnimationTimer() >= 14 || self.CurrentRule().IsVisited() ) && !self.IsCheckAnsClicked() && !self.IsQuestionView() )
{
if ( !self.CurrentActivity().IsReviewMode() && !self.CurrentActivity().IsCompleted() )
{
self.CurrentActivity().NoOfAttempts( self.CurrentActivity().NoOfAttempts() + 1 )
}
if ( section.IsError() && !section.IsAnswered() )
{
section.Color( '#EB6556' );
section.TextSize( 'bold' );
section.IsClicked( true );
if ( section.IsErrorFound == null )
{
section.IsErrorFound = ko.observable( true );
self.CurrentActivity().NoOfErrorFound( self.CurrentActivity().NoOfErrorFound() + 1 );
}
ShowQuestionView( section );
self.CurrentActivity().NoOfErrorAttempted( self.CurrentActivity().NoOfErrorAttempted() + 1 );
}
if ( section.IsError() && section.IsAnswered() && self.CurrentActivity().IsReviewMode() )
{
ShowReview( section );
}
}
}
//visiblity status of show error button
self.ShowErrorBtnVisibility = ko.computed( function ()
{
if ( self.CurrentActivity() != undefined )
{
return self.CurrentActivity().NoOfAttempts() > 7 && !self.CurrentActivity().IsShowErrorClicked() && !self.CurrentActivity().IsCompleted() && !self.IsQuestionView() && ( self.CurrentActivity().CurrentSection() == null )
}
else
{
return false;
}
} )
function ShowReview( section )
{
if ( self.CurrentActivity().CurrentSection() == section )
{
self.CurrentActivity().IsErrorReviewClicked( false );
self.CurrentActivity().CurrentSection( null );
}
else
{
self.CurrentActivity().CurrentSection( section );
self.CurrentActivity().IsErrorReviewClicked( true );
}
}
function ChangeQuestionReadOnlyState( status )
{
for ( var i = 0; i < self.CurrentActivity().Sections.length; i++ )
{
self.CurrentActivity().Sections[i].IsClicked = ko.observable( status );
}
}
self.ShowErrorClick = function ()
{
self.CurrentActivity().IsShowErrorClicked( true );
for ( var i = 0; i < self.CurrentActivity().Sections().length; i++ )
{
if ( self.CurrentActivity().Sections()[i].IsError() && !self.CurrentActivity().Sections()[i].IsAnswered() )
{
self.CurrentActivity().Sections()[i].TextSize( 'bold' );
self.CurrentActivity().Sections()[i].IsErrorFound = ko.observable( false );
}
}
};
self.CheckedOption = ko.observable( null );
//hold the answer status ie Correct InCorrect and PartiallyCorrect
self.IsCheckAnsClicked = ko.observable( false );
self.AllowIncorrectRuleAttempt = ko.observable( false );
var checkedOption;
self.CheckAnswerClick = function ()
{
if ( self.CurrentActivity().CurrentSection().IsRuleIdentified == null )
{
self.CurrentActivity().CurrentSection().IsRuleIdentified = ko.observable();
}
self.IsCheckAnsClicked( true )
var result = self.CheckedOption().IsAnswer();
checkedOption = self.CheckedOption();
if ( result )
{
self.CurrentActivity().NoOfRuleIdentified( self.CurrentActivity().NoOfRuleIdentified() + 1 );
self.CurrentActivity().CurrentSection().IsRuleIdentified( true );
self.CheckedOption( '' );
//retry not required for correct answer.
self.AllowIncorrectRuleAttempt( false );
ShowAnswer();
}
else
{
self.CurrentActivity().CurrentSection().IsRuleIdentified( false );
//reverse the retry for incorrect ans
if ( self.AllowIncorrectRuleAttempt() )
{
self.CheckedOption( '' );
self.AllowIncorrectRuleAttempt( false );
ShowAnswer();
}
else
{
self.AllowIncorrectRuleAttempt( true );
}
}
};
self.OptionClick = function ()
{
self.IsCheckAnsClicked( false );
return true;
}
function ShowAnswer()
{
if ( !self.AllowIncorrectRuleAttempt() )
{
var currentSection = self.CurrentActivity().CurrentSection();
if ( currentSection.IsRuleIdentified() && currentSection.IsErrorFound() )
{
currentSection.Color( '#7FCE14' );
UpdateAnsColor( '#7FCE14' );
}
else if ( currentSection.IsRuleIdentified() || currentSection.IsErrorFound() )
{
currentSection.Color( '#9983B4' );
UpdateAnsColor( '#9983B4' );
}
else
{
//if currentRule and error both not identified
currentSection.Color( '#EB6556' );
UpdateAnsColor( '#EB6556' );
}
currentSection.TextSize( 'bold' );
currentSection.IsAnswered( true );
}
self.IsQuestionView( false );
}
function UpdateAnsColor( color )
{
if ( self.CurrentRule().IsReview() )
{
var errorType = ko.utils.arrayFirst( self.CurrentActivity().ErrorTypes(), function ( errortype )
{
return self.CurrentActivity().CurrentSection().ErrorType.RuleId() == errortype.RuleId();
} );
if ( errorType != null )
{
for ( var i in errorType.AnsColors() )
{
if ( errorType.AnsColors()[i] == '#FFFFFF' )
{
errorType.AnsColors()[i] = color;
break;
}
}
}
}
else
{
for ( var i in self.CurrentActivity().AnsColors() )
{
if ( self.CurrentActivity().AnsColors()[i] == '#FFFFFF' )
{
self.CurrentActivity().AnsColors()[i] = color;
break;
}
}
}
}
self.FeedBackClick = function ()
{
if ( !self.IsQuestionView() && !self.CurrentActivity().IsCompleted() )
{
self.IsCheckAnsClicked( false );
self.CurrentActivity().CurrentSection( null );
ChangeQuestionReadOnlyState( false )
if ( self.CurrentActivity().NoOfErrorAttempted() == self.CurrentActivity().NoOfErrorPresent() )
{
self.CurrentActivity().IsCompleted( true );
UpdateScore();
currentSound = new buzz.sound( "audio/applause.ogg" );
currentSound.play();
}
}
return true;
};
function UpdateScore()
{
var currentRule = self.CurrentRule();
currentRule.NoOfErrorAttempted( currentRule.NoOfErrorAttempted() + self.CurrentActivity().NoOfErrorPresent() );
currentRule.NoOfRuleAttempted( currentRule.NoOfRuleAttempted() + self.CurrentActivity().NoOfErrorPresent() );
currentRule.NoOfErrorFound( currentRule.NoOfErrorFound() + self.CurrentActivity().NoOfErrorFound() );
currentRule.NoOfRuleFound( currentRule.NoOfRuleFound() + self.CurrentActivity().NoOfRuleIdentified() );
}
self.NextActivityClick = function ()
{
currentActivityIndex = self.CurrentRule().Activities.indexOf( self.CurrentActivity() ) + 1;
SetCurrentActivity( currentActivityIndex );
ResetCurrentValues();
ShowAnimation();
};
self.ReviewClick = function ()
{
self.CurrentActivity().CurrentSection( null );
self.CurrentActivity().IsReviewMode( true );
}
self.AnimationTimer = ko.observable( 0 );
var currentSound;
function PlayActivitySound()
{
if ( self.AnimationTimer() < 5 )
{
currentSound = new buzz.sound( 'audio/Activity/Activity' + self.CurrentRule().Id() + '.' + self.CurrentActivity().Id() + '.ogg' );
currentSound.play();
}
else
{
clearTimeout( timeOutID );
}
}
function UpdateTimer()
{
if ( self.AnimationTimer() <= 14 )
{
self.AnimationTimer( self.AnimationTimer() + 1 );
}
else
{
clearInterval( intervalID );
}
}
var intervalID;
var timeOutID;
//set the timer for sound play and animation in activity
function ShowAnimation()
{
if ( !self.CurrentRule().IsVisited() || isInstructionClicked )
{
//mark the activity as visited
self.CurrentRule().IsVisited( true );
isInstructionClicked = false;
intervalID = setInterval( UpdateTimer, 250 );
timeOutID = setTimeout( PlayActivitySound, 1000 );
}
}
self.Alphabets = 'abcdefghijklmnoqpuvwxyz';
self.MarkerAnimation = {
height: ko.observable( 0 ),
width: ko.observable( 0 )
}
self.AnimateMarkerMouseover = function ()
{
var height = 0;
var width = 0;
//check if animation is already running
if ( height <= 0 )
{
var intervalExpand = setInterval( function ()
{
if ( height < 42 )
{
height = height + 2;
width = width + 11;
self.MarkerAnimation.width( width );
self.MarkerAnimation.height( height );
}
}, 100 )
}
setTimeout( function ()
{
clearInterval( intervalExpand );
var intervalShrink = setInterval( function ()
{
height = height - 2;
width = width - 11;
self.MarkerAnimation.width( width );
self.MarkerAnimation.height( height );
}, 100 )
setTimeout( function () { clearInterval( intervalShrink ); }, 2300 )
}, 2500 )
}}
找到