Knockout.js 如何在knockoutjs映射插件中减少将viewmodel映射到json所需的时间

Knockout.js 如何在knockoutjs映射插件中减少将viewmodel映射到json所需的时间,knockout.js,knockout-mapping-plugin,Knockout.js,Knockout Mapping Plugin,我正在使用knockoutjs映射插件将我的viewmodel映射到json,但这需要大约1分钟的时间。映射后,json文件的大小约为275kb。下面是一个数据示例,我有一个长度为30的数组,每个数组包含这么多的数据。当将数据传递给viewmodel时,我会像ko.mapping.toJSON(数据)一样访问详细代码 $( document ).ready( function () { window.Data = ko.mapping.fromJS( data, d

我正在使用knockoutjs映射插件将我的viewmodel映射到json,但这需要大约1分钟的时间。映射后,json文件的大小约为275kb。下面是一个数据示例,我有一个长度为30的数组,每个数组包含这么多的数据。当将数据传递给viewmodel时,我会像ko.mapping.toJSON(数据)一样访问详细代码

$( 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 )


}}
$(文档).ready(函数()
{
window.Data=ko.mapping.fromJS(数据,数据映射);
if(localStorage.viewModels==null)
{
log(“本地存储中没有数据”);
window.CurrentViewModel=新的ViewModel();
ko.applyBindings(window.CurrentViewModel);
localStorage.Data=ko.mapping.toJSON(window.Data);
}
其他的
{
log('LoadRequiredView called');
Util.LoadRequiredView();
}
} );
函数ViewModel()
{
var self=这个;
self.CurrentView=ko.observable('start');
self.PreviousView=ko.observable('start');
self.LoginFocus=ko.可观察(假);
self.IsHomeViewVisited=ko.可观察(假);
self.PartScrollPosition=ko.可观察(0);
self.IsHomeHover=ko.可观察(假);
self.homehave=函数()
{
self.IsHomeHover(!self.IsHomeHover());
}
self.PartOnScroll=函数()
{
self.PartScrollPosition($('.tab节').scrollTop());
}
函数GotoView(视图)
{
//将当前视图存储在“上一个视图”中的“后退”按钮
如果(currentSound!=null)
{
currentSound.stop();
}
self.PreviousView(self.CurrentView());
self.CurrentView(视图);
如果(视图=‘主’)
{
$('.tab节').scrollTop(self.PartScrollPosition())
}
}
self.StartClick=函数()
{
GotoView(‘登录’);
self.LoginFocus(true);
}
self.LicenseClick=函数()
{
GotoView(“许可证”);
}
self.UserName=ko.observable(空);
self.CleaUserNameClick=函数()
{
self.UserName(空);
}
self.Rules=window.Data.Rules;
self.Parts=ko.observearray();
self.CurrentPart=ko.可观察(空);
self.ContinueClick=函数()
{
if(self.UserName()!=null)
{
if(self.Parts().length==0)
{
AddPartToParts();
}
self.CurrentPart(self.Parts()[0]);
GotoView(“家”);
如果(!self.IsHomeViewVisited())
{
self.IsHomeViewVisited(true);
var sound=新的嗡嗡声('audio/HomeScreen.ogg');
声音。播放();
}
}
}
函数AddPartToParts()
{
var startIndex=0;
var指数;
for(var i=1;i=self.Rules().length)
{
endIndex=self.Rules().length-1;
}
self.Parts.push({Id:ko.observable(self.Parts().length+1),Rules:ko.observactarray(self.Rules.slice(startIndex,endIndex+1)))
startIndex=endIndex+1;
}
}
函数AddExtraPropertiesToRules(规则)
{
对于(var i=0;i