1

私はasp.net mvc4とknockoutjsが初めてで、ビューがどのように機能するかを理解するのに助けが必要です.

  1. Shared フォルダーに _Layout.vbhtml があり、プロジェクト内のすべてのページの「マスター」ページです。

  2. 私はAccountController、HomeController、およびGrowerControllerを持っています

  3. Views フォルダーに GrowerController 用の Grower フォルダーがあります。Index は通常どおりデフォルトのビューです。

  4. Views/Grower/Index には、サーバーからデータを取得するノックアウト ViewModel があります。

  5. ここで、Home/Index などの他のビューに移動すると、ノックアウト ViewModel を作成したビューにいなくても、Firebug のコンソールにサーバーからデータを取得するための呼び出しが行われていることがわかります。

私は非常に混乱しています。すべてのページで _layout.vbhtml を使用しているために発生しますか? 私は何を間違っていますか?

編集: * _Layout.vbhtml*

    <!DOCTYPE html>
    <html lang="en">
      <head>
       <meta charset="utf-8" />
       <title>@ViewData("Title")</title>
       <meta name="viewport" content="width=device-width" />
       <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
       <link href="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.css" rel="stylesheet" type="text/css" />

        @* Javascrips files *@
        <script src="@Url.Content("~/Scripts/knockout-2.1.0.js")" type="text/javascript"></script>
        <script src="@Url.Content("http://code.jquery.com/jquery-1.7.1.min.js")" type="text/javascript"></script>
        <script src="@Url.Content("http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.js")" type="text/javascript"></script>
        <script src="@Url.Content("~/Scripts/custom.js")" type="text/javascript"></script>


        <!-- Custom stylesheet overriding styles -->
        @If Request.QueryString("pr") = "dow" or ViewData("pr") = "dow" Then
         @<link rel="stylesheet" href="@Url.Content("~/Content/CustomDow.css")" />
        Else
         @<link rel="stylesheet" href="@Url.Content("~/Content/Custom.css")" />
        End If
     </head>
     <body>
       <div data-role="page" data-theme="b">
        <div data-role="header">
            @If IsSectionDefined("Header") Then
                @RenderSection("Header")
            Else
                @<h1>@ViewData("Title")</h1>
                @Html.Partial("_LoginPartial")
            End If
        </div>
        <div data-role="content">
            @RenderBody()
        </div>
    </div>

    @RenderSection("scripts", required:=False)
</body>

栽培者/インデックス.vbhtml

    @Code
      ViewData("Title") = "Select a Grower/Branch"
    End Code

    @section scripts
      <script type="text/javascript">

      function SuperViewModel() {

        //====== GrowerInfo =======
        var self = this;
        self.GrowerName = ko.observable();
        self.GrowerCompany = ko.observable();
        self.GrowerAddress = ko.observable();
        self.ShowGrowerCompany = ko.observable();
        self.GrowerID = ko.observable();

        self.updateGrowerInfo = function () {
          $.getJSON("GetGrower", function (allData) {
          self.GrowerName(allData.Name);
          self.GrowerCompany(allData.CompanyName);
          self.GrowerAddress(allData.Address);
          self.ShowGrowerCompany(allData.ShowCompany);
          self.GrowerID(allData.ID);
         });
        };

        //Load initial state from server and populate viewmodel
        self.updateGrowerInfo();
        //========= End GrowerInfo ==========

         if ($("#hfFlag").val() == "1") {
          //========= BranchInfo ==========
          self.BranchName = ko.observable();
          self.Company = ko.observable();
          self.Address = ko.observable();
          self.ID = ko.observable();

          //Load initial state from server and populate viewmodel
          self.updateBranchInfo = function () {
           $.getJSON("GetBranch", function (allData) {
            self.BranchName(allData.Name);
            self.Company(allData.CompanyName);
            self.Address(allData.Address);
            self.ID(allData.ID);
          });
        };

        self.updateBranchInfo();
        //=========== End BranchInfo ==============
      }


      //=============== GrowerList ===============
      var MyGrower = function (data) {
       this.growerId = ko.observable(data.GrowerId);
       this.growerName = ko.observable(data.GrowerName);
     };

      self.growers = ko.observableArray([]);

      self.updateGrowers = function () {
        //refresh listview
        $("#ulGrowerList").listview();
        $("#ulGrowerList").listview("refresh");

      $.getJSON("GetGrowers", function (allData) {
        var mappedGrowers = $.map(allData, function (item) { return new MyGrower(item) });
        self.growers(mappedGrowers);


        });
      };

      self.setSelectedClassToGrowerList = function (item, event) {

        $(ulGrowerList).closest('ul').find('a').removeClass('highlight');
        $(ulGrowerList).closest('ul').find('.selected').remove();

        $(event.target).toggleClass("highlight");
        if ($(event.target).hasClass("highlight")) {
          $(event.target).append("<span class='selected'>Selected</span>");

          replaceByValue('GrowerID', event.target.id);
          postjsonToServerNow("grower");

          //update GrowerInfo 
          $.getJSON("GetGrower", function (allData) {
            self.GrowerName(allData.Name);
            self.GrowerCompany(allData.CompanyName);
            self.GrowerAddress(allData.Address);
            self.ShowGrowerCompany(allData.ShowCompany);
            self.GrowerID(allData.ID);
          });

        } else {
          $(event.target).find(".selected").remove();
        }
      };



      self.setSelectedClassToBranchList = function (item, event) {

        $(ulBranchList).closest('ul').find('a').removeClass('highlight');
        $(ulBranchList).closest('ul').find('.selected').remove();

        $(event.target).toggleClass("highlight");

        if ($(event.target).hasClass("highlight")) {
          $(event.target).append("<span class='selected'>Selected</span>");

          replaceByValue('BranchID', event.target.id);
          postjsonToServerNow("branch");
        } else {
          $(event.target).find(".selected").remove();
        }

      };



      //Load initial state from server and populate viewmodel
      self.updateGrowers();

      //============ End GrowerList =============
    }

    //============= End ViewModel Section ====================//


      $(document).bind('pageinit', function () {
        //enable ko
        ko.applyBindings(new SuperViewModel());


        $("#divBranchList").hide();

        //show hide lists
        $("#btnGrower").click(function () {
        $("#divGrowerList").show();
        $("#divBranchList").hide();
       });

       $("#btnBranch").click(function () {
         $("#divBranchList").show();
         $("#divGrowerList").hide();
       });

      });
    </script>
    End Section




    <table class="maintable" id="maintable">
      <tr>
        <td class="left">
          <div id="GrowerInfo">
            <strong>Grower</strong><br />
            <a data-role="button" data-theme="e" id="btnGrower" data-bind="click: updateGrowers">
              <h3>
               <span data-bind="text: GrowerName"></span>
              </h3>
              <span data-bind="text:GrowerCompany, visible: ShowGrowerCompany" class="block"></span><span data-bind="text: GrowerAddress">
              </span>
              <br />
              <span data-bind="text: GrowerID"></span>
            </a>
          </div>
          @If ViewData("IsDealer") Then
            @<div id="BranchInfo">
              <strong>Branch</strong> <a data-role="button" data-theme="e" id="btnBranch">
                <h3>
                  <span data-bind="text: BranchName"></span>
                </h3>
                <span data-bind="text: Company"></span>
                <br />
                <span data-bind="text: Address"></span>
                <br />
                <span data-bind="text: ID"></span></a>
            </div>
          End If
        </td>
        <td class="splitline">
        </td>
        <td class="right">
          <div class="content-right">
            <div id="divGrowerList" style="overflow: auto; height: 450px; padding: 10px;">

            <p>Total growers: <span data-bind="text: growers().length">&nbsp;</span></p>

               <ul data-inset="true" data-filter="true" data-bind="foreach: growers" data-role="listview" id="ulGrowerList">
                  <li><a data-bind="click: $parent.setSelectedClassToGrowerList, attr: {id: growerId}"><span data-bind="text: growerName, attr: {id: growerId}, click: $parent.setSelectedClassToGrowerList" /></a></li>
              </ul>

              <textarea name="growers" rows="10" data-bind="value: ko.toJSON(growers)"></textarea>

            </div>
            <div id="divBranchList">
              @If ViewData("IsDealer") Then
                @Html.Action("MyBranchList2")
              End If
            </div>
            @If ViewData("IsDealer") Then
              @<input type="hidden" id="hfFlag" value="1" />
            Else
              @<input type="hidden" id="hfFlag" value="0" />
            End If
          </div>
        </td>
      </tr>
    </table>
4

2 に答える 2

0

あなたの _Layout.vbhtml を見なければ、私は確かに言うことはできませんが、すべてのページで JavaScript を実行しているのでscript、_Layout.vbhtml にタグがある可能性があります。

したがって、これを Index.vbhtml に移動する<head>タグに配置するに@RenderSection("Scripts")は、Layout.vbhtml で a を使用し、ビューで次を使用します。

@Section "Scripts"

@<script>
    // write JS here or reference a file using the src attribute
</script>

End Section

これにより、Layout.vbhtmlの間@Section "SectionName"とその中にすべてが配置されます。End Section@RenderSection("Scripts")

編集:

one.beat.consumer へのコメントから、私はあなたの問題を見ていると思います。しかし、あなたのコードを見たことがないので、私はまだ推測していることを理解してください.jQuery Mobileを使用していたことに言及しなかったため、大きな問題です

通常の MVC4 Web アプリケーションと jQuery Mobile アプリケーションには大きな違いがあります。

1 つは、jQM を使用すると、常に同じページにいることです。サーバーから ajax を介してページをロードし、ページを<div data-role="page">...</div>. これは、セクションに特定のページのスクリプトを配置<head>すると、jQM によって無視される理由を説明しています。<head>無視されない唯一のセクションは、ロードされた元のページのセクションであり、常にあなたのホームページであるとは限りません

<head>したがって、特定のページのスクリプトをロードするために、 MVC セクションを使用して要素にスクリプトを配置することはできません。内でスクリプトを参照する必要があります<div data-role="page">ただし、ページをキャッシュしている場合、これは一度しか起動されず、pageshowもう一度起動したい場合はバインドする必要がある場合があります (おそらくビューモデルを更新するため)。

最後に、

pageinitハンドラーでビューモデルを適用していると言いました。これは、ページがサーバーから取得され、DOM に挿入されるたびに呼び出されます。

js をビューから除外したい場合は、_Layout.vbhtml でサイト全体の js ファイル (custom.js) を参照して、次<head>を使用できます。

$(document).on('pageinit', '#PageId', function(event) {
    /* do viewmodel stuff here */
});

<div data-role="page">これは、 withid="PageId"がフェッチされて DOM に挿入されるたびに実行されます。ここでは任意のセレクターを使用できるため.require-vm、ページclass="require-vm"が挿入されたときに起動するために使用できます。

于 2012-09-28T12:12:56.930 に答える
0

_layoutページで Knockout ViewModel を定義しました。

このビュー モデルをすべてのページで使用する場合は問題ありませんが、使用したくないようです。それを特定のアクション ビューに移動して分離します。

上記の Sethi へのコメントで、それを行うと JavaScript が機能しないと述べました...これは、レイアウトとビューの両方にスクリプト タグを配置したことが原因である可能性があります。knockout.js が読み込まれる前に、ビュー モデルを構築しようとしているに違いありません。

いい練習:

レイアウトでは、スクリプト タグをページの下部、</body>閉じるタグの直前に配置します。閉じる前の最後のタグRenderSection()は、設定したとおりに呼び出す必要があります。

これで、ビューのどこにでもこのスクリプト セクションを定義して、フレームワーク スクリプトの後に発生するようにすることができます。jQuery、ノックアウトなど

$.ready()また、jQuery では、スクリプトが DOM のロード後にのみ実行されるようにするために、ほとんどの場合、使用することが望ましいことを覚えておいてください。

于 2012-09-28T20:14:22.630 に答える