Martian code example: system settings (view reuse example in Asp.net mvc3)

Source: Internet
Author: User
Document directory
  • 1. First open up a second battlefield:
  • 2. Erase the storytreetype shadow in storytreetype1.
Features

Final Function

The preceding line shows the user story Tree Configuration interface of the Martian. There is a button (visible upon hovering) behind each user story. The operation menu appears after you click it, some of them are the sub-story menu.

If you select "general story" on the left and only one project is included in the menu, if you select "general story" on the right, there are many stories (subject to the constraints of the current story type, this is more complex and will be discussed later ).

In this Code, the keyword "storytreetype" will appear, "simple" on the left side (simple tree), and "leveled" on the right side (level tree ).

The following two graphs show the state chain configuration interface of the Martian. In the operation menu mentioned above, apart from creating a story, you can also transfer the current story to another State.

If you select the left-side Navigation Pane, the menu only includes the development-related status (new, to be developed, under development, after development, and after deployment, all statuses will appear (after the creation, there will be approval and other links, and the deployment process also includes multiple statuses ).

In this Code, the keyword "statuslist" will appear. The left side is "developmentonly" (only including the R & D status), and the right side is "all" (all ).

Obviously, not only are the two interfaces very similar, but the four interfaces are very similar to the models behind them. Let's talk about how to implement this configuration function with the smallest code.

Development Process

The Controller code is skipped, focusing on the encapsulation of model and view.

Step 1: Develop the Model Code of storytreetype

Public partial class product {public const string userdefaproduproductidkey = "defaultproductid"; // storytree type (simple, leveled, etc .) public const string storytreetypekey = "storytreetype"; Public Enum storytreetypes {simple = 0, leveled = 1} public static readonly storytreetypes [] storytreetypevalues = {storytreetypes. simple, storytreetypes. leveled}; public static readonly string [] storytreetypetexts = {"default (use a simple parent-child relationship to form a story tree)", "Use a system-defined story level to form a story tree "}; public storytreetypes storytreetype {get {return (storytreetypes) config. readvalueasint (storytreetypekey, "$" + id) ;}} Public String storytreetypetext {get {return storytreetypetexts [config. readvalueasint (storytreetypekey)] ;}}

Note that this code contains a class called config, which writes different configurations to a public table in the database. Therefore, we do not need to discuss the data storage issue to complete this function.

This benefits from the many functions that have been encapsulated by the Martian.

Step 2: implement the view of storytreetype

Note that the following code has already done foreach loop processing for the two types of stroytreetype, instead of writing them to the machine.

Sometimes I think there are only two types of loops, but if there is no loop, I need two very close sections of code, and debugging and maintenance are very difficult. And once this habit is developed, it is easy to scatter the entire software.

@ Foreach (VAR type in product. storytreetypevalues) {<TD style = "border: none;"> <Div class = "Help-sample"> <Table> <tr> <TD style = "border: none; width: 500px; "> @ mfcui. image ("", "/products/storytree/index16.png") <B> @ Product. storytreetypetexts [(INT) type] </B> @ if (model. storytreetype = type) {<B> [current settings] </B>} else {@ mfcui. link ("[enabled]", "/mfc/configs/ajaxset? Key = "+ product. storytreetypekey + "& value =" + (INT) Type + "& User = $" + model. ID, returnto: This) :}< table> <tr> <TD style = "border: none; width: 200px;"> @ renderpage ("~ /Areas/DLC/views/products/managementmethod/storytreetypes/_ "+ model. storytreetype + ". cshtml ") </TD> <TD style =" border: none; "> @ mfcui. image ("", "/products/managementmethods/_" + Type + "example.png ") <br/> </TD> </tr> </table> </div> </TD>}

Note:

1. In this Code, there is a file named "/mfc/configs/ajaxset ?... "Call, this call will directly complete the setup (written to the database), and immediately refresh the current page (note that there is a" returnto: this, is the encapsulation of the Martian returning to the current page ).

2. the top titles ("default (using simple parent-child relationship to form a story tree)" and "using a system-defined story level to form a story Tree"), pictures (the bottom one @ mfcui. image () is written on this page.

3. the two renderpages are used to display the "advantages", "disadvantages", and "Suggestions" text with large differences, which are stored in the two files respectively, and the file name is "model" in the renderpage. storytreetype is assembled.
2 and 3 indicate several important encapsulation principles in the MVC View:

A. Similar parts must be recycled out of a view and solved through splicing.

B. concatenate slightly different parameters using variables

C. The names of images and partial views must correspond to variables, so that they can be easily spliced.

D. Use partial view to process the largest difference.

Step 3: Draft the model section of statuslist"

(When I wrote this blog, my code was written here. In order to copy a little "Draft Code", I started to write it after the code is verified)

After years of encapsulation, I feel that the fastest way is stillTest Encapsulation,That is, write a part (storytreetype above), copy another similar part (statuslist below), observe its similarities and differences, and then encapsulate it.

Compared with designing encapsulation directly at the beginning, this method is easier to learn and accept, and has relatively low requirements on personnel. I have been programming for so many years, but I am still not sure to write the underlying layer directly to the blank screen in all circumstances, and then derive the subclass.

Note that the code in statuslist is directly copied, pasted, and modified. They are "Draft Code" to observe the encapsulation points. It will be replaced in the future.

Public partial class product {public const string userdefaproduproductidkey = "defaultproductid"; // storytree type (simple, leveled, etc .) public const string storytreetypekey = "storytreetype"; Public Enum storytreetypes {simple = 0, leveled = 1} public static readonly storytreetypes [] storytreetypevalues = {storytreetypes. simple, storytreetypes. leveled}; public static readonly string [] storytreetypetexts = {"default (use a simple parent-child relationship to form a story tree)", "Use a system-defined story level to form a story tree "}; public storytreetypes storytreetype {get {return (storytreetypes) config. readvalueasint (storytreetypekey, "$" + id) ;}} Public String storytreetypetext {get {return storytreetypetexts [config. readvalueasint (storytreetypekey)] ;}// status list type (developmentonly, allowed, etc .) public const string statuslisttypekey = "statuslisttype"; Public Enum statuslisttypes {developmentonly = 0, allowed = 1} public static readonly statuslisttypes [] statuslisttypevalues = {statuslisttypes. developmentonly, statuslisttypes. allowed}; public static readonly string [] statuslisttypetexts = {"default (only display development-related status)", "Use User-Defined allowable status "}; public statuslisttypes statuslisttype {get {return (statuslisttypes) config. readvalueasint (statuslisttypekey, "$" + id) ;}} Public String statuslisttypetext {get {return storytreetypetexts [config. readvalueasint (statuslisttypekey)] ;}}
Step 4: rewrite storytreetype and statuslist to a derived class of the base class

To be honest, this rewrite process failed. Five minutes later, we found that because each line of code is different, even if the rewrite is successful, the initialization code is no less than the code.

And the risk of giving up Enum is also raised, so the rewrite plan is terminated.

Step 5: rewrite the view for storytreetype to be able to process statuslist at the same time. Many new users may start to work directly at this time, but the following describes a tips: 1. first open up a second battlefield:
        <table class = "noborder">            <tr>                @RenderPage("~/Areas/Products/Views/Products/SetManagementMethods/_StoryTreeType.cshtml")            </tr>            <tr>                @RenderPage("~/Areas/Products/Views/Products/SetManagementMethods/_StoryTreeType1.cshtml", Product.StoryTreeTypeValues)            </tr>        </table>

The following _ storytreetype1.cshtml is copied and will be displayed below the original page, so that you can modify it and observe the new and old codes and their effects.

2. Erase the storytreetype shadow in storytreetype1.

The so-called shadow directly says "storytreetype" instead of a variable. Of course, each time one is erased, one more parameter is required. The pagedata [] parameter is used here (a new version of mvc3 ).

If you try it out, the sooner the problem occurs, the better.

Finally, the internal view becomes (note that there are no traces related to storytreetype ):

@ Foreach (VAR currentconfig in pagedata [0]) {<TD style = "border: none; "> <Div class =" Help-sample "> <Table> <tr> <TD style =" border: none; width: 500px; "> @ mfcui. image ("", pagedata [1]) <B> @ pagedata [2] [(INT) currentconfig] </B> @ if (pagedata [3] = currentconfig) {<B> [current settings] </B>} else {@ mfcui. link ("[enabled]", "/mfc/configs/ajaxset? Key = "+ pagedata [4] +" & value = "+ (INT) currentconfig +" & User = $ "+ model. ID, returnto: This) :}< table> <tr> <TD style = "border: none; width: 200px;"> @ renderpage (pagedata [5]) </TD> <TD style = "border: none;"> @ mfcui. image ("", page [6] + "_" + currentconfig + ". PNG ") <br/> </TD> </tr> </table> </div> </TD>}

The interface also becomes:

            <tr>                @RenderPage("~/Areas/Products/Views/Products/SetManagementMethods/_StoryTreeType.cshtml")            </tr>            <tr>                @RenderPage("~/Areas/Products/Views/Products/SetManagementMethods/_StoryTreeType1.cshtml",                     Product.StoryTreeTypeValues, "/Products/StoryTree/Index16.png", Product.StoryTreeTypeTexts, Model.StoryTreeType, Product.StoryTreeTypeKey,                    "~/Areas/DLC/Views/Products/ManagementMethod/StoryTreeType/_" + Model.StoryTreeType + ".cshtml",                    "/Products/Products/ManagementMethods/")            </tr>

Note that there are many input parameters in the second battlefield.

From the perspective of appearance, the display effects of the two views are identical (no Paster ).

Step 6: Add statuslist Processing

Delete the code of the first TR, copy a TR that processes statuslisttype, and gradually modify it to make it work:

        <table class = "noborder">            <tr>                @RenderPage("~/Areas/Products/Views/Products/SetManagementMethod/_StoryTreeType1.cshtml",                     Product.StoryTreeTypeValues, "/Products/StoryTree/Index16.png", Product.StoryTreeTypeTexts, Model.StoryTreeType, Product.StoryTreeTypeKey,                    "~/Areas/DLC/Views/Products/ManagementMethod/StoryTreeType/",                    "/Products/Products/ManagementMethod/StoryTreeType/")            </tr>            <tr>                @RenderPage("~/Areas/Products/Views/Products/SetManagementMethod/_StoryTreeType1.cshtml",                     Product.StatusListTypeValues, "/MFC/Statuses/Index16.png", Product.StatusListTypeTexts, Model.StatusListType, Product.StatusListTypeKey,                    "~/Areas/DLC/Views/Products/ManagementMethod/StatusListType/",                    "/Products/Products/ManagementMethod/StatusListType/")            </tr>        </table>

TIPS:
1. During the modification process, you should modify a parameter to check whether it is still working.

2. modify the data that is unlikely to cause errors first, for example, modify "/mfc/statuses/index16.png", product. the statuslisttypetexts parameters are basically non-error because they are text.

Check the final result (there is a problem with the screen display because two images are missing ):

The file name of _ storytreetype1.cshtml is inappropriate in the future, because it can complete any system configuration in one line of code (including a title, several optional items, a set of descriptions, A picture), so the next step is to modify its name and place it in the appropriate place. But in our own habits, we will first change the name and then place it where it was originally used. Until the next time it is actually used again, discuss where it is appropriate. The official saying of this sentence is "Use it before reusing it". If it manages these four interfaces now, let it take care of them and wait for a while. The summary process includes writing this blog, which takes about 2 hours. Some may ask: it takes only one hour to copy and paste four pages. Why is it so hard? There are several reasons: 1. In the future, we will have more than 20 such settings pages. According to the encapsulation described above, you only need to add a line of code to the view for each generated page. 2. because we do not have any artist, we may change the page effect in the future, and these pages must maintain the same style. 3. Some technical changes may be made in the future, such as the config. These changes do not want to modify a lot of code.

In fact, the entire Martian product is generated in this type of building block code. Many unexpected things are as long as 1 ~ Two lines of code can be called (story tree, organization chart, burn-out chart, and all menus (each menu is delayed )......)

Once this habit is developed, the code will become more refined, and the writing process will become more and more simple.

I am participating in the csdn blog Star Selection. If you have read and liked this article, please vote:Http://vote.blog.csdn.net/item/blogstar/cheny_com

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.