ホームページ  >  記事  >  ウェブフロントエンド  >  angularjs と ajax_AngularJS を組み合わせて使用​​する詳細な例

angularjs と ajax_AngularJS を組み合わせて使用​​する詳細な例

WBOY
WBOYオリジナル
2016-05-16 15:35:371765ブラウズ

これは、ajax での easyui の使用に関する記事であり、angularjs の使用法も紹介し、angularjs の威力を実感することができます。インターネット上には ajax に関する記事がたくさんあります。ネイティブ httpxmlrequest オブジェクトの js から直接書き込みを開始することはありません。そういうものを読むのは、どのようなレベルのことが起こっているのか、原理は何なのかを理解するためだけです。そのようなコードを使用してサイト全体を記述します。 html js のようなものは、最初に設計されたときに十分に考慮されておらず、単なるデタラメです。幸いなことに、このクソをもっと簡単にもっと美味しくするのに役立つさまざまなフレームワークがあります。幸いなことに、インターネット産業の発展により、ブラウザ側のこうしたことは統一規格の方向に発展しつつあります。

Web フォーム ページ HelloAjaxNet.aspx を作成しましょう。まず、ajax について話しましょう。ここでは、インターネット上で広く配布されている AjaxPro.2.dll を使用します。これは個人の作品です。とても使いやすいです。 もともと、新しい asp.net には、webmethod 属性を使用して宣言されたサーバー側のメソッドと、クライアント側の pagemethod アクセス メソッドが付属しています。さまざまなオブジェクトも json でデジタル化でき、機能は上記と同じです。 Microsoft には、aspx の codebehind が付属しています。webconfig については、新しいバージョンの vs2013 開発環境で設定する必要はありません。新しい ajax Web サイト プロジェクトを作成します。 webconfig は自動的に完了します。その後、サーバー ページが ScriptManager にロードされます。クライアントは runat=server および ee503d583a91f9715bf6cf1578ad4c40 ca6b66ce984e7a13d89428526c49237a これにより、クライアントはページメソッドを使用してアクセスできるようになります。

やはり上記の方が便利だと思います。その原理については多くは言いません。ページがロードされると、サーバー オブジェクトが登録され、生成された HTML ページにはさらにいくつかの文が含まれます

 <script type="text/javascript" src="/ajaxpro/prototype.ashx"></script>
 <script type="text/javascript" src="/ajaxpro/core.ashx"></script>
 <script type="text/javascript" src="/ajaxpro/converter.ashx"></script>
 <script type="text/javascript" src="/ajaxpro/WebApplication.StudentsInfo,WebApplication.ashx"></script>
 <script type="text/javascript" src="/ajaxpro/WebApplication.Grad,WebApplication.ashx"></script>
 <script type="text/javascript" 
src="/ajaxpro/WebApplication.NewFolder.HelloAjaxNet,WebApplication.ashx"></script>
 <script type="text/javascript" src="/ajaxpro/WebApplication.DataEntity,WebApplication.ashx"></script>
なぜ、js ファイル ajaxpro/WebApplication1.NewFolder2.HelloAjaxNet,WebApplication1.ashx を参照するためですか?

クライアントで js を呼び出すためのこのスクリプトはサーバーによって自動的に生成され、サーバーとまったく同じ名前であることがわかります。その後、クライアントでサーバー メソッドをコールバックできます。魔法のようなことは何もありません。はい、私たちは主にこの機能と json データの利便性を利用して、クライアントとサーバー間のデータのシームレスな転送を実現したいと考えています。

JSON データのシリアル化について。以前は、手動解析には外部の JSON ライブラリまたは Microsoft 独自のライブラリしか使用できませんでした。

サーバー:

public string ServerProcerMethod(string stu)
     {
       //System.Web.Script.Serialization.JavaScriptSerializer jsSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
       //StuInfo s= jsSerializer.Deserialize<StuInfo>(stu);
 
       System.Web.Script.Serialization.JavaScriptSerializer jsSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
       List<StuInfo> s = jsSerializer.Deserialize<List<StuInfo>>(stu);
       if (s != null && s.Count > )
       {
         StuInfo stu= s[];
         StringBuilder sb = new StringBuilder();
         jsSerializer.Serialize(stu, sb);
         return sb.ToString();
       }
       else
         return null;
     }
クライアント:

//javascript 字符串转json对象:
 var obj = JSON.parse(str);
 //javascript json 对象转字符串:
 JSON.stringify(obj);
AjaxPro.2.dll と ajax.dll の関係については、ネット上では違うと言われていますが、基本的には一人でやっているのでしょう。上記の Web サイトから ajaxpro をダウンロードしてください。これが完璧なバージョンです

dll ファイルを参照した後、webconfig httphandler を設定する必要があります。この機能は、上記の ashx リクエストを ajaxpro コードに転送し、クライアント js がサーバー メソッドを直接呼び出せるようにすることです。

<system.webServer>
   <directoryBrowse enabled="true"/>
   <handlers>
    <add verb="*" path="*.ashx" name="myhandler" type="AjaxPro.AjaxHandlerFactory,AjaxPro."/>
    <!--<add verb="POST,GET" path="ajax/*.ashx" name="myhandler" type="Ajax.PageHandlerFactory, Ajax" />-->
   </handlers>
  </system.webServer>
それ以降はサーバー コードを直接見ていきますので、これ以上は言いません。

easyui は拡張コントロールの集まりとして理解できます。 jquery と同じように、js オブジェクトとネイティブ HTML コントロールをその内容とともにパッケージ化し、データを便利に処理するために作成されたメソッドのいくつかをクリックすることができます。また、デフォルトのコントロールの外観も問題なく、エンタープライズ管理ソフトウェアにとっては非常に優れています。他のソフトウェアにとっては、これしかありません。 easyui ファイルをダウンロードしてプロジェクトに配置し、easyui 関連の js、スタイル ファイル、jquery を導入します。

<script type="text/javascript" src="../jquery-easyui-../jquery.min.js"> </script>
   <link rel="stylesheet" type="text/css" href="../jquery-easyui-../themes/default/easyui.css" />
   <link rel="stylesheet" type="text/css" href="../jquery-easyui-../themes/icon.css" />
   <script type="text/javascript" src="../jquery-easyui-../jquery.easyui.min.js"></script>
次に、easyui のホームページで紹介されているように、easyui を使用して、CSS スタイルまたは JS コードを通じてネイティブ HTML コントロールを easyui コントロールにレンダリングできます
http://jeasyui.com/

 <div class="easyui-dialog" style="width:px;height:px"
   data-options="
     title:'My Dialog',
     iconCls:'icon-ok',
     onOpen:function(){}">
   dialog content.
 </div>
 <input id="cc" style="width:px" />
 $('#cc').combobox({
   url: ...,
   required: true,
   valueField: 'id',
   textField: 'text'
 });
はい、とても便利です。実際、中国には優れた JS ライターが数多くおり、このような UI を作成しているので、これを使用することにしましょう。最も一般的に使用される要件は、ajax サーバー側のページングです。

まずこの easyui データグリッドについて話しましょう。さらに悪いことに、クライアント HTML に table タグを追加します。16431938812a1ada99e05ed4bffa024df16b1740fad44fb09bfe928bcc527e08 次に、js を使用して次のようにします。 $( '#studb').datagrid() は、それを easyui datagrid コントロールにレンダリングします。これは document.ready() で行うことができます。データ テーブルにデータを入力する必要があります。このデータはどこから取得されますか? どの列が表示されますか? 各ページに表示される項目の数は次のとおりです。 Easyui は、次のデータグリッドなど、さまざまな場所で一連のパラメーターを JSON オブジェクトの形式で受け取ります:

具体看loader 和columns ,loader用于定义你以什么形式载入数据 定义了loader上面的url就没有必要了。

我这里的WebApplication1.NewFolder2.HelloAjaxNet.BindData(param.keyword, param.page, param.rows) 自然也是服务端的方法 用于检索数据的 。

关于这三个param.keyword, param.page, param.rows 是我们用于实现loader时 easyui那种设计方式故意暴露给我们的参数 方便我们使用。

param.keyword 是我们上面定义的 我们点搜索的时候需要往服务端传一个查询关键词 queryParams: { keyword: keywordStr }

param.page 是easyui自己的参数表示当前第几页 param.rows表示每页行数,每当你 点表格的 上一页 下一页 的时候 就会自动往loader 发翻页的参数 这个是自动的。

然后就从服务端获取数据填充表格 ,就是这么一个工作过程。 还有colums 我就不说了就是定义显示哪些列 和自定义列 那个很容易看懂。

easyui控件有属性 方法,调用方法 的形式总算像这样 :$('#studb').datagrid('reload')  这就相当于调用了#studb这个表格控件的reload方法了 然后数据就会自动刷新,每个控件的具体见文档。

服务端数据处理我们还是用entityframework 我一般都用codefirst的方式 这东西跟他自己的mssql数据库 结合的很好 用起很方便。

服务端代码:

//查询(带分页
     [AjaxPro.AjaxMethod]
     public static WebApplication.DataEntity BindData(string keyword, int page, int rows)
     {
       //, ref int pageIndex, out int totalPage
       if (keyword == null)
         keyword = "";
       int pageIndex = ;
       int pageSize = ;
       int totalPage;
       if (page != )
         pageIndex = page;
       if (rows != )
         pageSize = rows;
       MyDb db = new MyDb();
       var data = from studentInfo in db.Students where studentInfo.name.Contains(keyword) select new 
{ stuNo = studentInfo.stuNo, name = studentInfo.name, age = studentInfo.age, gradName = studentInfo.grad.gradName };
       //var data = from studentInfo in db.Students where studentInfo.name.Contains(keyword) select studentInfo;
       totalPage = data.Count() % pageSize == &#63; data.Count() / pageSize : data.Count() / pageSize + ;
       if (pageIndex > totalPage)
         pageIndex = totalPage;
       else if (pageIndex < )
         pageIndex = ;
       //var dt = DataList<object>.Create(data.OrderBy(r => r.stuNo), new StudentsInfo(), pageIndex, pageSize).Value;
       object dt=null ;
       if(data.Count()>)
       dt= DataList<object>.Create(data.OrderBy(r => r.stuNo),
         new { stuNo = , name = "", age = , gradName = "" }, pageIndex, pageSize).Value;
       WebApplication.DataEntity result = new WebApplication.DataEntity();
       result.total = data.Count();
       result.rows = dt;
       return result;
     }

关于数据部分 和EF linq 分页那些我就不贴出来了 完整示例下载里面有。走走看吧 试试看吧 完全无刷新 服务端分页,感觉棒棒哒

 

搜索那个我也不想说了哈 就是重新载入下数据而已,删除是通过自定义 列的方式 传id到js函数 然后调用服务端删除。然后要说下 录入功能 以及easyui自带 的表单验证也是相当方便的。

新建一个div 作为弹出层 里面有一个录入信息的表格 各种html控件 只要写上easyui对应的样式  就自动渲染了 看弹出层的  class="easyui-dialog" data-options="closed:true,title:'新学生注册',modal:true"

其实很简单噻看字面意思就明白了 这些参数 都在easyui的文档里有。验证 也是在html元素上写data-options 就可以了, :

<div id="addBox" class="easyui-dialog" data-options="closed:true,title:'新学生注册',modal:true" style="width: px; height: px">
       <table class="auto-style">
         <tr>
           <td>学生姓名:</td>
           <td>
             <input id="stuname" class=" easyui-textbox" data-options="required:true,missingMessage:'必填项!',validType:'email',invalidMessage:'email格式不正确!'" type="text" /></td>
         </tr>
         <tr>
           <td>班级: </td>
           <td>
             <input class="easyui-combobox" id="grad" name="grad"
               data-options="valueField:'id',textField:'gradName',required:true,missingMessage:'必填项!'" /></td>
         </tr>
         <tr>
           <td>
             <input id="saveBtn" onclick="saveClick()" type="button" value="保存" /></td>
           <td>
             <input id="Button" type="button" onclick="$('#addBox').dialog('close');" value="关闭" /></td>
         </tr>
       </table>
     </div>

新建按钮:

复制代码 代码如下:

 5708f134602dab1c472ae16b57ea6246加新的5db79b134e9f6b82c0b36e0489ee08ed

注意千万别用button 元素  就是这种 bb9345e55eb71822850ff156dfde57c8新加的65281c5ac262bf6d81768915a4a77ac0  这是个坑 ,折腾了好久。

保存按钮调用 的js函数:

 //保存信息
     function saveClick() {
       var isvaliok = $("#addBox").form('validate');//包起来的需要提交信息的那个div框的id
       if (isvaliok == false) {
         $.messager.show({ title: '提示', msg: '请完善不正确的项后再提交', showType: 'show' });
         return;
       }
       var stu = {};
       stu.name = $("#stuname").val();
       stu.age = ;
       stu.GradId = $("#grad").combobox('getValue');
       stu.gradName = $("#grad").combobox('getValue');
       if (isNaN(stu.GradId))
         stu.GradId = null;
       var rst = WebApplication.NewFolder.HelloAjaxNet.addStu(stu);
       if (rst.value == "ok") {
         $('#addBox').dialog('close');
         $('#studb').datagrid('reload');
         var gradData = WebApplication.NewFolder.HelloAjaxNet.getGrad().value;
         $('#grad').combobox({ data: gradData }).combobox('reload');
       }
       else {
         $.messager.show({ title: '提示', msg: rst.error.Message + rst.value, showType: 'show' });
       }
     }

注意到了噻:

 var isvaliok = $("#addBox").form('validate');//包起来的需要提交信息的那个div框的id
       if (isvaliok == false) {
         $.messager.show({ title: '提示', msg: '请完善不正确的项后再提交', showType: 'show' });
         return;
       }

在easyui里进行验证很简单噻 只要在html代码里把验证格式定义好了 ,只需要传入一个最外面容器控件的id $("#addBox").form('validate') 就自动帮我们验证了。并且界面上还有提示 焦点自动放到第一个验证不通过的控件上去了 完全不需要我们动手。

当然我们在客户端 document.ready()的时候 必须要绑定表格和下拉框的数据:

 $(function () {
       //页面初始化
       //载入表格数据
       bindDataToTb();
       //载入班级下拉框
       var gradData = WebApplication.NewFolder.HelloAjaxNet.getGrad().value;
       $('#grad').combobox({ data: gradData }).combobox('reload');
       var fd = new FormData();
     });

服务端保存的代码:

//添加
     [AjaxPro.AjaxMethod]
     public string addStu(StudentsInfo stu)
     {
       MyDb db = new MyDb();
       if(stu.GradId==null)
       {
         if (string.IsNullOrEmpty(stu.gradName) == false)
         {
           Grad grd = new Grad();
           grd.gradName = stu.gradName;
 
           Grad grdOld = db.grads.FirstOrDefault(r => r.gradName == stu.gradName);
           if(grdOld!=null)
           {
             return "类别已存在";
           }
           else
           {
             db.grads.Add(grd);
             stu.grad = grd;
           }
         }
       }
       db.Students.Add(stu);
       db.SaveChanges();
       return "ok";
     }

服务端代码  如果我们没有这个id的类别我们就认为这个类别是新的 ,新加一个类别 然后立即绑定 perfect 完美 ,棒棒哒

 

看上去是不是有模有样。做管理类软件还行。

这样ui 那样ui当你需要自定义样式的时候发现什么ui都是浮云,例如我说的国内的写js比较牛的 就已经造出来很多ui了 ,表格是很漂亮 很强大。 其实很多功能你还是用不到 你想改还很困难 当然我的js也是很菜的。 当你用到另一套ui 的时候又要熟悉它那一套 。我只想用个简简单单的自定义分页表格而已 或者像asp.net里的服务器控件repeat 流式布局 四个数据一行那种 你怎么做。 还是自己动手吧。php里面有前端模板。

我这里只是简单从实际需求了解下angular的威力 php里面模板什么的都是浮云   新建一个webform  HelloAjaxNetAngular.aspx

注意这个例子  服务端代码我一律用上面的丝毫都不会变 只是前端变了,angularjs 的主打思想是mvvm 模式 就是wpf里面那种依赖属性 动态绑定 ,不知道你们用过没 反正我用过 感觉就一个字 爽 ,做这种数据库平台程序 mfc winform 都是渣。

angularjs 的基础我就不介绍了 哈 直接从需求入手 做一个分页表格 加 信息更新 功能

angularjs的网站是 http://www.angularjs.org/ 这个网址在国内也是访问不了的。一些相关的其他人的学习笔记有 http://www.angularjs.cn/ http://www.zouyesheng.com/angular.html

反正这两个教程看了下对我没 对我没起到啥作用 感觉跟嚼木渣样的 ,angularjs的理念虽然是mvvm 但是angularjs本身还是感觉晦涩难懂。

我就在这样一个半懂不懂的状态下写了这个例子 ,所有的操作 几乎都完全不需要向jquery那样动dom 。真心感觉到了他的强大。前端就一个controller函数 管整个页面,怎么一个一个的分 我也不明白 只知道controller 跟html限定一样的树状结构。没在范围的html元素不能访问其controller里的 变量。

我们来看这个controller 函数 ,我写的时候也没什么感觉 。就是感觉很存粹 就只感觉到两个东西存在 。业务逻辑在操作数据。 就像在写c#数据操作代码样:

 function myCtr($scope) {
       var mod = [{ name: 'xiang', age: }, { name: 'xiang', age: }, { name: 'xiang', age: }];
       $scope.data = mod;
       $scope.curobj = {};
       $scope.pageEntity = { total: , rows: , page: , pgmsg: '' }
       //初始化默认第一页
       $scope.initPage = function () {
         var firstPage = WebApplication.NewFolder.HelloAjaxNetAngular.BindData($("#txtkeyword").val(), $scope.pageEntity.page, $scope.pageEntity.rows);
         $scope.data = firstPage.value.rows;
         var pageEntityMod = {};
         pageEntityMod.total = firstPage.value.total;
         pageEntityMod.rows = $scope.pageEntity.rows;
         pageEntityMod.page = $scope.pageEntity.page;
         var totalpage = pageEntityMod.total % pageEntityMod.rows == &#63;
           parseInt(pageEntityMod.total / pageEntityMod.rows) :
           parseInt(pageEntityMod.total / pageEntityMod.rows) + ;
         pageEntityMod.pgmsg = "共 " + pageEntityMod.total + "条记录 每页 " + pageEntityMod.rows
           + "条,共 " + totalpage + "页 ,当前第 " + pageEntityMod.page + "页";
         $scope.pageEntity = pageEntityMod;
         $scope.curobj = {};
       }
       //更新当前 选定的
       $scope.modifyCur = function () {
         var rst = WebApplication.NewFolder.HelloAjaxNetAngular.updateStu($scope.curobj)
         //刷新表格 当前选中信息 复原
         $scope.initPage();
         alert(rst.value);
       }
       //下翻页
       $scope.nextPage = function () {
         var totalpage = $scope.pageEntity.total % $scope.pageEntity.rows == &#63;
           parseInt($scope.pageEntity.total / $scope.pageEntity.rows) :
           parseInt($scope.pageEntity.total / $scope.pageEntity.rows) + ;
         var pagenewnum = $scope.pageEntity.page + ;
         if (pagenewnum <= totalpage)
           $scope.pageEntity.page += ;
         $scope.initPage();
       }
       //上翻页
       $scope.previousPage = function () {
         var pagenewnum = $scope.pageEntity.page - ;
         if (pagenewnum >= )
           $scope.pageEntity.page -= ;
         $scope.initPage();
       }
       //搜索
       $scope.search = function () {
       }
       //选中一行
       $scope.del = function (sender, curobj) {
         //所有行的颜色还原//设置选中那一行的颜色
         var rows = $(sender.target).parent().parent().parent().find("tbody").find("tr");
         for (var i = ; i < rows.length; i++) {
           $(rows[i]).css("background", "white");
         }
         $(sender.target).parent().css("background", "#ffed");
         $scope.curobj = curobj;
       }
       //首次先调用下 以获取第一页
       $scope.initPage();
     }

界面部分:

<div ng-controller="myCtr" id="mygrid">
         <input id="txtkeyword" type="text" /><input ng-click="initPage()" type="button" value="搜索" />
         <br />
         <br />
         <div style="height: px">
           <table cellspacing="" border="" class="gridtable">
             <thead>
               <th width="px">name</th>
               <th width="px">age</th>
             </thead>
             <tbody ng-repeat="stu in data">
               <tr ng-click='del($event,stu)' style="background-color: white">
                 <td>{{stu.name}}</td>
                 <td>{{stu.age}}</td>
               </tr>
             </tbody>
           </table>
 
         </div>
         <div id="pager">
           <a href="#" ng-click="previousPage()">上一页</a> <a href="#" ng-click="nextPage()">下一页</a>
           <span>{{pageEntity.pgmsg}}</span>
         </div>
 
         <div>
           姓名:<input type="text" value="{{curobj.name}}" ng-model="curobj.name" /><br />
           年龄:<input type="text" value="{{curobj.age}}" ng-model="curobj.age" />
           <input id="Button" type="button" ng-click="modifyCur()" value="更改" />
         </div>
       </div>

easyui の datagrid のローダーを自作したのを見ました。ページング情報を取得するための最初のリクエストの後、すぐにデータをテーブルにバインドし、テンプレートの作成とまったく同じようにして、独自のページング コントロールを初期化していることがわかります。 ng-click を使用すると、以前と同様にクライアントのクリックがトリガーされ、その後コントローラー内のメソッドが呼び出されてデータが更新されます。データはビジネス ロジックに従って更新されるだけであり、何もする必要がないことに注意してください。それ以外。上記 2 つのコードが理解できない場合は、angularjs とデータ バインディングを開始するのに 10 分もかかりません。

WPF のような双方向バインド メカニズムにより、データ モデル データが更新されると、それに応じてページ コンテンツも自動的に変更されます。下のテキスト ボックスのデータを編集すると、上の表のデータが送信される前に変更されることもわかります。データが同じ場所から取得されているため、ajax であるように感じられます。

上記のすべての例のプロジェクト ソース コードはダウンロードして直接実行できますが、いくつかの外部ライブラリを導入しているため、10MB に収まるには大きすぎます

言いたいこと

実際、インターネットがこのように発展し続ければ、フロントエンドは統合され、その頃には Web ページがシステムとクライアントになるでしょう。 バックエンドはデータとセキュリティのみを担当します。 HTML5 は今やほぼ業界標準になっているのではないでしょうか?

とりあえず、フロントエンドとバックエンドが同じモデル上で動作するMVCモードについて話している人をブログガーデンで何人か見かけましたが、フロントエンドが属性を更新する際に自動的に更新する仕組みがあります。永続化のためにバックエンドを更新します。データベースに移動するか、バックエンドのモデルの特定の属性を更新すると、フロントエンド HTML ページの値が自動的に変更されます。 やっぱりできないわけではないので、人材はたくさんいるので、少なくともまだ安定していないのだと思います。

さまざまな UI には、easyui、ligerui、fineui、miniui、Devexpress などの多くの JS フレームワーク、seajs、requirejs、JavaScriptMVC、backbone、avalonjs、knockout、angular、jquery、jqueryui、js は本当にクソです。あらゆる種類のフレームワークを学習し終えることはできません

特にソフトウェア業界は日々変化しています。フレームワークやプラットフォームに基づいたテクノロジーが多すぎます。しかし、技術者としては、そのテクノロジーに習熟していなくても問題はありません。 、少なくとも 1 つまたは 1 つのテクノロジーに習熟している必要があります。そうでない場合、私は基本的にまだレンガを動かす途中にいるのが残念です。ビジネスコードを書くということは、1 年の経験を 10 年間使うことを意味します。優秀なプログラマーがこの種のデータベース システムに取り組んでいる限り、ビジネス コードを書くのは仕事の後に行われます。長い間、彼は自分でそれを行う方法を知っているでしょう。それは、独自のツール ライブラリと経験を蓄積するために、すぐに開発できるいくつかのいわゆる小さなフレームワークを開発することになります。

仕事に偏見を持たないでください。毎日ビジネスコードを書くことができる限り、ソフトウェア開発は単なる職業ではなく、問題を解決することが目的ではありません。

私は個人的に js があまり好きではありません。これが最初に設計されたとき、js は完璧ではなく、それを使用する際にさまざまな障害を引き起こしました。ここでフロントエンドの作業を行う人々に対して偏見はありません。Situ Zhengmei など、フロントエンドに精通した人々がこれらの Web サイト プログラムを簡単に完成できるようにするツールを作成してくれたことに感謝します。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。